如何在 JavaScript 中按多列对多维数组进行排序? [英] How does one sort a multi dimensional array by multiple columns in JavaScript?

查看:27
本文介绍了如何在 JavaScript 中按多列对多维数组进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一整天都在解决这个问题,但没有一个好的解决方案.谷歌也帮不上什么忙.我有一个脚本需要接受行/列数未知的二维数组.该脚本还需要接受一个包含要排序的列列表的一维数组,以及另一个包含要排序的顺序的数组.调用看起来有点像这样:

I've been working on this problem all day without a good solution. Google has been little help as well. I have a script that needs to accept a two dimensional array with an unknown number number of rows/columns. The script also needs to accept a one dimensional array containing a list of columns to sort by, and another containing the order to sort by. The call will look a little like this:

var orderList = {0,4,3,1};
var orderDir = {asc,desc,desc,asc};
dataArr = do2DArraySort(dataArr, orderList, orderDir);

函数 do2DArraySort 应该返回按第一列(升序)、第五列(降序)、第三列(降序)、第二列(降序)排序的 dataArr 数组).我能够使用下面的代码将其设置为两层深,但是一旦我尝试添加第三个排序列,它就会崩溃.我明白为什么,但我想不出一个让它发挥作用的好方法.

The function do2DArraySort should return the dataArr array sorted by the first column (in ascending order), then by the fifth (in descending order), then by the third (in descending order), then by the second (in descending order). I was able to make it two levels deep using the code below, but it fell apart once I tried adding a third sort column. I understand why, but I can't figure out a good way to make it work.

有没有标准的方法来做到这一点?有人可以指出我可以在线学习和用作模板的好脚本吗?或者有人可以建议修改我的代码以使其正常工作?

Is there a standard way of doing this? Could someone point me to a good script online I can study and use as a template? Or can someone suggest a modification to my code to make it work?

谢谢!

//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;
}

推荐答案

数组字面量 [] 优于 new Array.符号 {0,4,3,1} 无效,应为 [0,4,3,1].

The array literal [] is preferred over new Array. The notation {0,4,3,1} is not valid and should be [0,4,3,1].

是否需要重新发明轮子?可以使用以下方法连接两个数组:

Is there a need for reinventing the wheel? Two arrays can be joined using:

originalArray = originalArray.concat(addArray);

元素可以使用:

array.push(element);

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

Arrays have a method for sorting the array. By default, it's sorted numerically:

// sort elements numerically
var array = [1, 3, 2];
array.sort(); // array becomes [1, 2, 3]

数组也可以反转.继续前面的例子:

Arrays can be reversed as well. Continuing the previous example:

array = array.reverse(); //yields [3, 2, 1]

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

To provide custom sorting, you can pass the optional function argument to 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"]
 */

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

Elements will retain their position if the element equals an other element. Using this, you can combine multiple sorting algoritms. You must apply your sorting preferences in reverse order since the last sort has priority over previous ones. To sort the below array by the first column (descending order) and then the second column (ascending order):

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]
 */

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

To sort latin strings (i.e. English, German, Dutch), use String.localeCompare:

array.sort(function (element_a, element_b) {
    return element_a.localeCompare(element_b);
});

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

To sort date's from the Date object, use their milliseconds representation:

array.sort(function (element_a, element_b) {
    return element_a.getTime() - element_b.getTime();
});

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

You could apply this sort function to all kind of data, just follow the rules:

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

x is the result from comparing two values which should be returned by a function passed to array.sort.

  1. x <0:element_a 应该在 element_b
  2. 之前
  3. x = 0:element_aelement_b 相等,元素不交换
  4. x >0:element_a 应该在 element_b
  5. 之后
  1. x < 0: element_a should come before element_b
  2. x = 0: element_a and element_b are equal, the elements are not swapped
  3. x > 0: element_a should come after element_b

这篇关于如何在 JavaScript 中按多列对多维数组进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆