[英]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.