在javascript中排序多维数组时的行为不一致

时间:2015-07-04 17:58:13

标签: javascript arrays sorting

我有两个阵列,我试图改变,然后用两个相似但不同的方法排序。一个是正​​确的,而另一个是不是。

数组#1:

var scale = [
    [["C","C"], 1],
    [["D","D"], 2],
    [["E","E"], 3],
    [["F","F"], 4],
    [["G","G"], 5],
    [["A","A"], 6],
    [["B","B"], 7],
]

阵列#2:

var scale = [
    [["C","C"], 1],
    [["D","D"], 2],
    [["Eb","Eb"], 3],
    [["F","F"], 4],
    [["G","G"], 5],
    [["Ab","Ab"], 6],
    [["Bb","Bb"], 7],
]

我使用此方法进行排序:

this.sortScale = function (a,b) {
    a = a[1];
    b = b[1];
    return a == b ? 0 : (a < b ? -1 : 1);
}

然后将该方法插入到每个阵列的另一个方法中。

对于第一个数组:

this.relativeMinor = function(scale) {
    for (var counter = 3; counter <=9; counter++) {
        if (counter > 7) {
            scale[counter - 3].splice(1, 1, counter - 7);
        } else {
            scale[counter - 3].splice(1, 1, counter);
        }
    }
    scale.sort(this.sortScale);
    console.log(scale);
    return scale;
};

对于第二个阵列:

this.relativeMajor = function(scale) {
    for (var counter = 0; counter <=6; counter++) {
        if (counter > 1) {
            scale[counter].splice(1, 1, counter - 1);
        } else {
            scale[counter].splice(1, 1, counter + 6);
        }
    }
    scale.sort(this.sortScale);
    console.log(scale);
    return scale;
};

我希望数组#1能够像这样出现,而且它正在工作:

数组#1:

var scale = [
    [["A","A"], 1],
    [["B","B"], 2],
    [["C","C"], 3],
    [["D","D"], 4],
    [["E","E"], 5],
    [["F","F"], 6],
    [["G","G"], 7],
]

我希望数组#2能够像这样出现,它不能正常工作:

var scale = [
    [["Eb","Eb"], 1],
    [["F","F"], 2],
    [["G","G"], 3],
    [["Ab","Ab"], 4],
    [["Bb","Bb"], 5],
    [["C","C"], 6],
    [["D","D"], 7],
]

相反它出现了这样:

var scale = [
    [["Ab","Ab"], 4],
    [["Bb","Bb"], 5],
    [["C","C"], 6],
    [["D","D"], 7],
    [["Eb","Eb"], 1],
    [["F","F"], 2],
    [["G","G"], 3],
]

我错过了什么?

注意:在我的程序中,在给定时间内只会调用两种方法中的一种(缩放是通过一个按键创建唯一的相对Major,并使用不同的按键来创建相对的Minor),所以我不会认为这是使用&#34; scale&#34;适用于this.relativeMinorthis.relativeMajor

1 个答案:

答案 0 :(得分:0)

我通常不建议在这样的代码中修改原始数组。相反,复制它们并处理副本。或者您是否有理由需要修改原件?

此外,您可以编写一个方法来处理这两种情况,而不是复制两种方法中的代码,而是使用指定起始比例数的参数。

你根本不需要进行任何排序!只需按照您想要的顺序编写一个包含元素的新数组。

我打算将其作为普通函数编写,以便在浏览器控制台中轻松进行测试;您可以进行适当的更改以使其成为方法。

var majorScaleC = [
    [["C","C"], 1],
    [["D","D"], 2],
    [["E","E"], 3],
    [["F","F"], 4],
    [["G","G"], 5],
    [["A","A"], 6],
    [["B","B"], 7],
];

var minorScaleC = [
    [["C","C"], 1],
    [["D","D"], 2],
    [["Eb","Eb"], 3],
    [["F","F"], 4],
    [["G","G"], 5],
    [["Ab","Ab"], 6],
    [["Bb","Bb"], 7],
];

// Return a relative scale based on an existing scale and starting
// at a specified scale number.
// Note that the scale numbers start at 1, and array indices at 0.
function relativeScale( scaleFrom, start ) {
    var scaleTo = [];
    for( var i = 0;  i < scaleFrom.length;  ++i ) {
        scaleTo.push([
            scaleFrom[ ( i + start - 1 ) % scaleFrom.length ][0],
            i + 1
        ]);
    }
    return scaleTo;
}

function relativeMinor( minorScale ) {
    return relativeScale( minorScale, 6 );
};

function relativeMajor( majorScale ) {
    return relativeScale( majorScale, 3 );
};

console.log( JSON.stringify( relativeMinor(majorScaleC) ) );
console.log( JSON.stringify( relativeMajor(minorScaleC) ) );

此日志:

[[["A","A"],1],[["B","B"],2],[["C","C"],3],[["D","D"],4],[["E","E"],5],[["F","F"],6],[["G","G"],7]]

[[["Eb","Eb"],1],[["F","F"],2],[["G","G"],3],[["Ab","Ab"],4],[["Bb","Bb"],5],[["C","C"],6],[["D","D"],7]]