繁体   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