如何在JavaScript中按多列对多维数组进行排序?

Nic*_*las 10 javascript arrays sorting multidimensional-array

我一整天都在努力解决这个问题而没有一个好的解决方案.谷歌一直没有什么帮助.我有一个脚本需要接受具有未知数量的行/列的二维数组.该脚本还需要接受一维数组,该数组包含要排序的列列表,另一个包含要排序的顺序.电话会看起来像这样:

var orderList = {0,4,3,1};
var orderDir = {asc,desc,desc,asc};
dataArr = do2DArraySort(dataArr, orderList, orderDir);
Run Code Online (Sandbox Code Playgroud)

函数do2DArraySort应返回按第一列(按升序排序)排序的dataArr数组,然后按第五列(按降序排序),然后按第三列(按降序排序),再按第二列(按降序排序)排序.我可以使用下面的代码将其设置为两级,但是一旦我尝试添加第三个排序列,它就会崩溃.我理解为什么,但我无法找到一个好的方法来使它工作.

有这样做的标准方法吗?有人能指出我在线的好脚本,我可以学习并用作模板吗?或者有人建议修改我的代码以使其工作?

谢谢!

//appends an array content to the original array
function addToArray(originalArray, addArray) {
    if (addArray.length != 0) {
        var curLength = 0;
        curLength = originalArray.length;
        var maxLength = 0;
        maxLength = curLength + addArray.length;  
        var itrerateArray = 0;
        for (var r = curLength; r < maxLength; r++) {   
            originalArray[r] = addArray[itrerateArray];
            itrerateArray++;
        }
    }
}

function do2DArraySort(arrayToBeSorted, sortColumnArray, sortDirectionArray) {
    if (arrayToBeSorted == "undefined" || arrayToBeSorted == "null") return arrayToBeSorted;
    if (arrayToBeSorted.length == 0) return arrayToBeSorted;
    if (sortColumnArray.length == 0) return arrayToBeSorted;
    tempArray = arrayToBeSorted; 
    var totalLength = sortColumnArray.length; 
    for(var m = 0; m < totalLength; m++) {
        if (m == 0) {   
            doBubbleSort(tempArray, tempArray.length, sortColumnArray[m], sortDirectionArray[m]);         
        } else {     
            doMultipleSort(tempArray, sortColumnArray[m], sortColumnArray[m-1], sortDirectionArray[m]);
        }
    } 
    return tempArray;
}

//check if a value exists in a single dimensional array
function checkIfExists(arrayToSearch, valueToSearch) {
    if (arrayToSearch == "undefined" || arrayToSearch == "null") return false;
    if (arrayToSearch.length == 0) return false;
    for (var k = 0; k < arrayToSearch.length; k++) {
        if (arrayToSearch[k] == valueToSearch) return true;
    }
    return false;
}

//sorts an 2D array based on the distinct values of the previous column
function doMultipleSort(sortedArray, currentCol, prevCol, sortDirection) {
    var resultArray = new Array(); 
    var newdistinctValuesArray = new Array();
    //finding distinct previous column values 
    for (var n = 0; n < sortedArray.length; n++) {
        if (checkIfExists(newdistinctValuesArray, sortedArray[n][prevCol]) == false) newdistinctValuesArray.push(sortedArray[n][prevCol]);
    }
    var recCursor = 0;
    var newTempArray = new Array(); var toStoreArray = 0; 
    //for each of the distinct values
    for (var x = 0; x < newdistinctValuesArray.length; x++) {
        toStoreArray = 0;
        newTempArray = new Array();  
        //find the rows with the same previous column value
        for (var y = 0; y < sortedArray.length; y++) {
            if (sortedArray[y][prevCol] == newdistinctValuesArray[x]) {
                newTempArray[toStoreArray] = sortedArray[y];
                toStoreArray++;
            }
        }       //sort the row based on the current column
        doBubbleSort(newTempArray, newTempArray.length, currentCol, sortDirection);
        //append it to the result array
        addToArray(resultArray, newTempArray);
    }
    tempArray = resultArray;
}
Run Code Online (Sandbox Code Playgroud)

Lek*_*eyn 25

数组文字[]首选new Array.符号{0,4,3,1}无效,应该是[0,4,3,1].

是否需要重新发明轮子?可以使用以下两种阵列连接:

originalArray = originalArray.concat(addArray);
Run Code Online (Sandbox Code Playgroud)

可以使用以下元素将元素附加到末尾:

array.push(element);
Run Code Online (Sandbox Code Playgroud)

数组有一种排序数组的方法.默认情况下,它按数字排序:

// sort elements numerically
var array = [1, 3, 2];
array.sort(); // array becomes [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

阵列也可以反转.继续上一个例子:

array = array.reverse(); //yields [3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

要提供自定义排序,可以将可选函数参数传递给array.sort():

array = [];
array[0] = [1, "first element"];
array[1] = [3, "second element"];
array[2] = [2, "third element"];
array.sort(function (element_a, element_b) {
    return element_a[0] - element_b[0];
});
/** array becomes (in order):
 * [1, "first element"]
 * [2, "third element"]
 * [3, "second element"]
 */
Run Code Online (Sandbox Code Playgroud)

如果元素等于另一个元素,则元素将保留其位置.使用此功能,您可以组合多个排序算法.您必须以相反的顺序应用排序首选项,因为最后一种排序优先于以前的排序.要按第一列(降序)和第二列(升序)对下面的数组进行排序:

array = [];
array.push([1, 2, 4]);
array.push([1, 3, 3]);
array.push([2, 1, 3]);
array.push([1, 2, 3]);
// sort on second column
array.sort(function (element_a, element_b) {
    return element_a[1] - element_b[1];
});
// sort on first column, reverse sort
array.sort(function (element_a, element_b) {
    return element_b[0] - element_a[0];
});
/** result (note, 3rd column is not sorted, so the order of row 2+3 is preserved)
 * [2, 1, 3]
 * [1, 2, 4] (row 2)
 * [1, 2, 3] (row 3)
 * [1, 3, 3]
 */
Run Code Online (Sandbox Code Playgroud)

要对拉丁字符串(即英语,德语,荷兰语)进行排序,请使用String.localeCompare:

array.sort(function (element_a, element_b) {
    return element_a.localeCompare(element_b);
});
Run Code Online (Sandbox Code Playgroud)

要从Date对象中对日期进行排序,请使用它们的毫秒表示:

array.sort(function (element_a, element_b) {
    return element_a.getTime() - element_b.getTime();
});
Run Code Online (Sandbox Code Playgroud)

您可以将此排序功能应用于所有类型的数据,只需遵循以下规则:

x是比较传递给函数应该返回的两个值的结果array.sort.

  1. x < 0:element_a应该来之前element_b
  2. x = 0:element_a并且element_b相等,元素不会被交换
  3. x > 0:element_a应该来之后element_b

  • 这是一个非常好的答案,但有一个问题:Lekensteyn说明了Array.prototype.sort()方法,"如果元素等于另一个元素,则Elements将保留其位置",但ECMAScript规范明确指出实现不必须这样做,有些浏览器不这样做.Chrome没有,Opera也没有.因此,您不能期望对sort()的多个后续调用以您希望跨浏览器的方式运行. (2认同)