簡體   English   中英

我可以使用嵌套sort()對嵌套數組進行排序嗎?

[英]Can i sort nested array using nested sort()?

這應該是輸入數組

var a = [2,1,3,4,1,[4,6,2,4],2,4,1];

對於輸出,我有兩種情況:-(內部數組的索引不變)

a = [1,1,2,3,4,[2,4,4,6],1,2,4]

a = [1,1,1,2,2,[2,4,4,6],3,4,4]

這就是我正在嘗試使用的:-

a.sort(function(a,b){
  if(b instanceof Array){
    b.sort();
  }
})

您可以遍歷數組並刪除所有子數組並保存其索引,然后對新數組進行排序,然后再次將排序后的子數組推入特定索引。

樣品

 var arr = [2, 1, 3, 4, 1, [4, 6, 2, 4], 2, 4, 1]; var arr1 = [2, 1, 3, 4, 1, [4, 6, 2, 4], 2, 6, 4, [4, 5, 3], 1, 2, 1, 3] var a = [2,1,3,4,1,[4,6,[4,5,[7,3,2,1,6],1,2],2,4],2,4,1]; function mySort(arr) { var _list = []; arr.forEach(function(item, index) { if (Array.isArray(item)) { _list.push({ index: index, value: arr.splice(index, 1).pop() }); } }); arr.sort(); _list.forEach(function(item) { arr.splice(item.index, 0, mySort(item.value)) }) return arr; } console.log(mySort(arr.slice())) console.log(mySort(arr1.slice())) console.log(mySort(a.slice())) 

編輯1

受到joey-etamity的回答的啟發,使其成為嵌套結構的通用名稱。

如果有數組元素,我建議拼接數組。 然后對數組排序並重新組裝數組。

該建議從背面進行迭代,並在拼接時保持陣列完整。

 function sort(array) { var i = array.length, inside = []; while (i--) { if (Array.isArray(array[i])) { inside.unshift({ pos: i, value: sort(array.splice(i, 1)[0]) }); } } array.sort(function (a, b) { return a - b; }); inside.forEach(function (a) { array.splice(a.pos, 0, a.value); }); return array; } var a = [2, 1, 3, 4, 1, [4, 6, 2, 4], 2, 4, 1]; console.log(sort(a)); 

這是完美的解決方案,使用嵌套函數調用對數組進行排序。

首先,存儲所有數組位置和子數組。

其次,將數字提取到新數組中

最后,將排序后的數組插入到與以前相同的位置。

 var a = [2,1,3,4,1,[4,6,[4,5,[7,3,2,1,6],1,2],2,4],2,4,1]; function nestedSort(arr){ var items = []; var numArr = []; for ( key in arr){ if (arr[key] instanceof Array) { items.push({index:key,array:arr[key]}); }else{ numArr.push(arr[key]); } } numArr.sort(); for (key in items){ numArr.splice(items[key].index,0,nestedSort(items[key].array)); } return numArr; } console.log(nestedSort(a)); 

[
  1,
  1,
  1,
  2,
  2,
  [
    2,
    4,
    [
      1,
      2,
      [
        1,
        2,
        3,
        6,
        7
      ],
      4,
      5
    ],
    4,
    6
  ],
  3,
  4,
  4
]

希望這可以解決您的問題。 :)

Array.sort()並非用於處理部分Array,這是您需要的,但是我們可以通過預處理數據(將其與其他信息包裝在一起),然后進行排序並最后進行提取,來解決此問題。原始值:

情況1:對數組之間的部分進行排序
[2,1,3,4,1,[4,6,2,4],2,4,1] -> [1,1,2,3,4,[2,4,4,6],1,2,4]

function sort1(arr){
    //I add an artificial "property" of to the values, to "describe" the groups, and to be able to sort by
    //each Array is it's own group (so they stay in order), and the values in between share the same group
    var group = 0, 
        isArray = false;

    //an intermediate Array holding all the information (in order) to either apply it to the current Array, or to return (map) it as a new Array
    var intermediate = arr.map(function(v,i){
        //last value was an Array, this is the first value after an Array, start a new group
        if(isArray) ++group;    

        if(isArray = Array.isArray(v)){ //update isArray
            v = sort1(v);               //recursive sorting
            ++group;                    //the last group just ended here
        }

        //return a composition, that contains all the data I need to sort by
        return {
            group: group,
            value: v
        }
    }).sort(function(a, b){
        //forst sort by group, and (only) if two values share the same group, sort by the original value
        return a.group - b.group || a.value - b.value
    });

    //apply data to current Array
    intermediate.forEach(function(obj, i){ arr[i] = obj.value });
    return arr;

    //return new Array
    //return intermediate.map(function(obj){ return obj.value });
}

情況2:將Array視為第一個值
[2,1,3,4,1,[4,6,2,4],2,4,1] -> [1,1,1,2,2,[2,4,4,6],3,4,4]

function sort2(arr){
    //an utility to fetch the first non-array value recursively
    function _value(v){ 
        while(Array.isArray(v)) v = v[0];
        return v;
    }

    var intermediate = arr.map(function(v, i){
        if(Array.isArray(v)) v = sort2(v);
        return {
            index: i,
            value: v,
            sortingValue: _value(v)
        }
    }).sort(function(a, b){
        return a.sortingValue - b.sortingValue || a.index - b.index;
    });

    //apply data to current Array
    intermediate.forEach(function(obj, i){ arr[i] = obj.value });
    return arr;

    //return new Array
    //return intermediate.map(function(obj){ return obj.value });
}

不,您沒有將sort調用放入比較函數中。 您將自下而上地遍歷數組,並將它們一個接一個地排序。 在您的情況下,如果它只是另一個數組中的一個,則可能甚至不需要遞歸:

a.forEach(function(element) {
   if (Array.isArray(element))
       element.sort(function compare(a, b) { return a-b; });
})

(我在這里選擇了一個簡單的數值compare )。

然后對外部數組進行排序:

a.sort(function compare(a, b) {
    if (Array.isArray(a)) a = a[0];
    if (Array.isArray(b)) b = b[0];
    return a - b;
})

(在這里, compare將數組的第一個元素與其他數字進行比較)。

我認為這樣使用Array.prototype.sort會更好:

 // var arr = [2, 1, 3, 4, 1, [4, 6, 2, 4], 2, 4, 1]; var arr = [2, 1, 3, 4, 1, [4, 6, 2, 4], 2, 6, 4, [4, 5, 3], 1, 2, 1, 3]; var chunks = chunkate(arr) console.log(JSON.stringify(chunks)); chunks.forEach(ch => ch.sort(_sort)); var result = chunks.reduce((p, c) => p.concat(c)); console.log(JSON.stringify(result)); function _sort(a, b) { var isAa = Array.isArray(a), isAb = Array.isArray(b); isAb && b.sort(_sort); return (isAa || isAb) ? 0 : a - b; } function chunkate(arr) { return arr.reduce((a, c) => { Array.isArray(c) ? a.push(chunkate(c), []) : a[a.length - 1].push(c) return a; }, [[]]); } 

這個怎么運作?

如果要比較的項目是數組,則不應替換它們,因此通過發送false排序函數可以識別出無需替換。 否則,簡單的比較就是答案。

編輯

正如評論中所討論的,最好將值分隔為多個塊,然后對每個部分進行排序,然后再次合並部分。 如果嵌套深度僅為一級,則可以使用默認排序(不帶_sort函數),但要注意用於嵌套數組的數組中的數組。 所以排序應該像這樣改變:

chunks.forEach(ch => Array.isArray(ch[0])? ch[0].sort(): ch.sort());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM