一个人如何排序多个列中的JavaScript多维数组? [英] How does one sort a multi dimensional array by multiple columns in JavaScript?

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

问题描述

我一直对这个问题都一天没有一个好的解决方案。谷歌一直没有太大的帮助为好。我有一个需要接受行/列的数目不详数目的二维数组的脚本。该脚本也需要接受包含列的列表排序由一维数组,另一种含顺序排序。此次电话会议将看起来有点像这样:

  VAR orderList = {0,4,3,1};
VAR orderDir = {递增,递减,递减,递增};
dataArr = do2DArraySort(dataArr,orderList,orderDir);

该函数do2DArraySort应该返回dataArr阵列由第一柱(以升序)进行分类,然后通过第五(以降序),再由第三(降序),然后由第二(以降序)。我能深刻的是两个层面使用下面的code之作,但它土崩瓦解一次我尝试添加第三个排序列。我明白为什么,但我不能想出一个好办法,使其工作。

是否有这样做的标准方法?可能有人点我一个好的剧本网上我可以学习和作为模板?或者,可以有人建议修改我的code,使其工作?

谢谢!

  //追加数组内容与原始数组
功能addToArray(originalArray,addArray){
    如果(addArray.length!= 0){
        变种curLength = 0;
        curLength = originalArray.length;
        变种最大长度= 0;
        最大长度= curLength + addArray.length;
        变种itrerateArray = 0;
        对于(VAR R = curLength;为r最大长度; R ++){
            originalArray [R] = addArray [itrerateArray]
            itrerateArray ++;
        }
    }
}功能do2DArraySort(arrayToBeSorted,sortColumnArray,sortDirectionArray){
    如果(arrayToBeSorted ==未定义|| arrayToBeSorted ==空)返回arrayToBeSorted;
    如果(arrayToBeSorted.length == 0)返回arrayToBeSorted;
    如果(sortColumnArray.length == 0)返回arrayToBeSorted;
    tempArray = arrayToBeSorted;
    VAR totalLength = sortColumnArray.length;
    为(变量M = 0; M&下; totalLength; M +){
        如果(M == 0){
            doBubbleSort(tempArray,tempArray.length,sortColumnArray [M],sortDirectionArray [M]);
        }其他{
            doMultipleSort(tempArray,sortColumnArray [M],sortColumnArray [M-1],sortDirectionArray [M]);
        }
    }
    返回tempArray;
}//检查是否在单维数组存在价值
功能checkIfExists(arrayToSearch,valueToSearch){
    如果(arrayToSearch ==未定义|| arrayToSearch ==空)返回false;
    如果(arrayToSearch.length == 0)返回false;
    对于(VAR K = 0; K< arrayToSearch.length; k ++){
        如果(arrayToSearch [K] == valueToSearch)返回true;
    }
    返回false;
}//排序基础上,previous列的不同值的二维数组
功能doMultipleSort(sortedArray,currentCol,prevCol,sortDirection){
    VAR resultArray =新的Array();
    VAR newdistinctValues​​Array =新的Array();
    //寻找不同的previous列值
    对于(VAR N = 0; N< sortedArray.length; N ++){
        如果(checkIfExists(newdistinctValues​​Array,sortedArray [N] [prevCol])==假)newdistinctValues​​Array.push(sortedArray [N] [prevCol]);
    }
    变种recCursor = 0;
    VAR newTempArray =新的Array();变种toStoreArray = 0;
    //为每个不同的值
    为(变量X = 0; X&下; newdistinctValues​​Array.length; X ++){
        toStoreArray = 0;
        newTempArray =新的Array();
        //找到具有相同previous列值的行
        对于(VAR Y = 0; Y< sortedArray.length; Y ++){
            如果(sortedArray [Y] [prevCol] == newdistinctValues​​Array [X]){
                newTempArray [toStoreArray] = sortedArray [Y];
                toStoreArray ++;
            }
        } //排序基于当前列上的行
        doBubbleSort(newTempArray,newTempArray.length,currentCol,sortDirection);
        //追加到结果数组
        addToArray(resultArray,newTempArray);
    }
    tempArray = resultArray;
}


解决方案

数组文本 [] 是preferred超过新的Array 。记号 {0,4,3,1} 是无效的,应该是 [0,4,3,1]

是否有必要重新发明轮子?两个阵列可以使用加入:

  originalArray = originalArray.concat(addArray);

元素可以使用追加到末尾:

 的Array.push(元);

阵列具有用于排序的阵列的方法。默认情况下,它的数字顺序排序:

  //排序数字元素
变种数组= [1,3,2];
的Array.Sort(); //数组变为[1,2,3]

阵列也可被颠倒。继续previous例如:

  =阵列array.reverse(); //收益率[3,2,1]

要提供自定义排序,你可以通过可选的功能参数中的Array.sort()

 阵列= [];
阵列[0] = [1,第一元件];
阵列[1] = [3,第二元件];
阵列[2] = [2,第三元件];
中的Array.sort(功能(element_a,element_b){
    返回element_a [0] - element_b [0];
});
/ **阵列将(按顺序):
 * [1,第一要素]
 * [2,第三个元素]
 * [3,第二元件]
 * /

如果元素等于一个其他元素的元素将保留自己的位置。利用这一点,你可以结合多种排序algoritms。您必须将自己的排序preferences以相反的顺序自上次排序超过previous那些具有优先权。排序下面阵列的第一列(降序),然后第二列(升序):

 阵列= [];
的Array.push([1,2,4]);
的Array.push([1,3,3]);
的Array.push([2,1,3]);
的Array.push([1,2,3]);
//排序的第二列
中的Array.sort(功能(element_a,element_b){
    返回element_a [1] - element_b [1];
});
//排序第一列,反向排序
中的Array.sort(功能(element_a,element_b){
    返回element_b [0] - element_a [0];
});
/ **结果(注意,第3列未排序,所以行2 + 3的次序是preserved)
 * [2,1,3]
 * [1,2,4](行2)
 * [1,2,3](第3行)
 * [1,3,3]
 * /

要拉丁文字符串(例如英语,德语,荷兰语)进行排序,可以使用 String.localeCompare

 中的Array.sort(功能(element_a,element_b){
    返回element_a.localeCompare(element_b);
});

要排序从日期目标日期的,用自己的毫秒重新presentation:

 中的Array.sort(功能(element_a,element_b){
    返回element_a.getTime() - element_b.getTime();
});

您可以应用这种功能对所有类型的数据,只是遵循的规则:

X 是比较应由传递给中的Array.sort 函数返回两个值的结果。


  1. X< 0 : element_a 应该在 element_b

  2. X = 0 element_a element_b 是相等,元件没有交换

  3. X> 0 : element_a 应该在 element_b

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);

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?

Thanks!

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

解决方案

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);

Elements can be appended to the end using:

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]

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

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

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 is the result from comparing two values which should be returned by a function passed to array.sort.

  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天全站免登陆