我可以使用嵌套排序()对嵌套数组进行排序吗?

时间:2016-07-24 12:46:43

标签: javascript arrays loops sorting

这应该是输入数组

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

6 个答案:

答案 0 :(得分:1)

您可以循环遍历数组并删除所有子数组并保存其索引,然后对新数组进行排序,并再次在特定索引上推送已排序的子数组。

示例



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答案的启发,使其成为嵌套结构的通用。

答案 1 :(得分:1)

这是完美的解决方案,使用嵌套函数调用来排序数组。

  

首先,存储所有数组位置和子数组。

     

其次,将数字提取到新数组中,

     

最后将排序后的数组插入到与之前相同的位置。



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
]

希望这可以解决您的问题。 :)

答案 2 :(得分:1)

Array.sort()不是为处理部分数组而构建的,在你的情况下你需要什么,但是我们可以通过预处理数据(用附加信息包装它)来解决这个问题,然后排序并在结束,提取原始值:

案例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:将数组视为第一个值 [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 });
}

答案 3 :(得分:0)

不,您没有将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将数组的第一个元素与其他数字进行比较)。

答案 4 :(得分:0)

如果元素有数组,我建议拼接数组。然后对数组进行排序并重新组装数组。

此提议从后面迭代并在拼接时保持数组完整。



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




答案 5 :(得分:-1)

我认为以这种方式使用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());