[英]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()))
受到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.