簡體   English   中英

JavaScript-對2D數組進行數字排序

[英]JavaScript - Sort 2D array, numerically

 function getCombinations(_list) { var fn = function(active, rest, a) { if (!active.length && !rest.length) return; if (!rest.length) { a.push(active); } else { fn(active.concat(rest[0]), rest.slice(1), a); fn(active, rest.slice(1), a); } return a; } return fn([], _list, []); } var list = [1, 2, 3, 4] console.log(getCombinations(list)); 

它返回一個二維數組,其中填充了每個組合...

[ [ 1, 2, 3, 4 ]
, [ 1, 2, 3 ]
, [ 1, 2, 4 ]
, [ 1, 2 ]
, [ 1, 3, 4 ]
, [ 1, 3 ]
, [ 1, 4 ]
, [ 1 ]
, [ 2, 3, 4 ]
, [ 2, 3 ]
, [ 2, 4 ]
, [ 2 ]
, [ 3, 4 ]
, [ 3 ]
, [ 4 ]
]

但是我想要以下命令

[ [ 1 ]
, [ 1, 2 ]
, [ 1, 2, 3]
, [ 1, 2, 3, 4 ]
, [ 1, 2, 4]
, [ 1, 3 ]
, [ 1, 3, 4 ]
, [ 1, 4 ]
, [ 2 ]
, ...
, [ 4 ]
]

我嘗試使用.sort ,但是按字母順序對組合進行排序

getCombinations([ 1, 2, 10 ]).sort()
// [ [ 1 ]
// , [ 1, 10 ]
// , [ 1, 2 ]
// , [ 1, 2, 10 ]
// , [ 10 ]
// , [ 2 ]
// , [ 2, 10 ]
// ]

但這不是我想要的順序。

如何對數組進行排序,以便對數組的內容進行數字處理,結果的順序與我上面提到的順序相同?

您可以使用函數代替之后的排序,該函數可以直接創建所需的組合作為排序結果。

 function getCombinations(list) { function iter(index, values) { var temp = values.concat(list[index]); result.push(temp); if (++index < list.length) { iter(index, temp); iter(index, values); } } var result = []; iter(0, []); return result; } var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; result = getCombinations(list); console.log(result.length); console.log(result.map(a => a.join(' '))); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

您可以將比較器函數傳遞給實現所需排序邏輯的sort()

arr.sort((one, other) => {
    let minL = Math.min(one.length, other.length);
    for (let i = 0; i < minL; i++) {
        if (one[i] != other[i]) return one[i] - other[i];
    }
    return one.length - other.length;
});

這是用功能編程標記的,所以我想我會展示一種按正確順序生成組合的功能方法。

通過函數 ,我的意思是使用僅對輸入參數(而不是依賴於外部狀態)操作並返回值(而不是依賴於突變)的函數。 這與命令式風格形成直接對比。

使用Array.prototype.sort既不是必需的,也不是功能性的(它會改變其輸入),因此在此答案中將不會使用它。

您還提到自編寫遞歸程序以來已經有一段時間了。 這應該使車輪再次旋轉!

 const identity = x => x const concat = (xs, ...ys) => ys.length === 0 ? xs : xs.concat (concat (...ys)) const subsets = ([ x, ...xs ], _return = identity) => xs.length === 0 ? _return ([ [ x ] ]) : subsets ( xs , ss => _return ( concat ( [ [ x ] ] , ss.map (s => concat ([ x ], s)) , ss ) ) ) for (const set of subsets ([ 1, 2, 3, 4 ])) console.log (set) 

正確訂購

[ 1 ]
[ 1, 2 ]
[ 1, 2, 3 ]
[ 1, 2, 3, 4 ]
[ 1, 2, 4 ]
[ 1, 3 ]
[ 1, 3, 4 ]
[ 1, 4 ]
[ 2 ]
[ 2, 3 ]
[ 2, 3, 4 ]
[ 2, 4 ]
[ 3 ]
[ 3, 4 ]
[ 4 ]

相關信息: 功率設置 –盡管該程序無法生成正確的順序,但其簡化形式顯示了如何開始考慮自己解決問題的方法。 concat現在是基本的二進制操作, powerSet具有簡化的邏輯分支。

 const identity = x => x const concat = (xs, ys) => xs.concat (ys) const None = Symbol () const powerSet = ([ x = None, ...xs ], _return = identity) => x === None ? _return ([ [] ]) // base case: no X : powerSet // inductive case: at least one X ( xs , ss => _return ( concat ( ss.map (s => concat ([ x ], s)) , ss ) ) ) console.log (powerSet ([ 'x', 'y', 'z' ])) // [ [ 'x', 'y', 'z' ] // , [ 'x', 'y' ] // , [ 'x', 'z' ] // , [ 'x' ] // , [ 'y', 'z' ] // , [ 'y' ] // , [ 'z' ] // , [] // ] 

盡管不那么復雜, powerSet甚至可以使用空輸入,使其成為一個完整的功能

getCombinations ([])
// => undefined

subsets ([])
// => [ [ undefined ] ]

powerSet ([])
// => [ [] ]

您可以使用如下比較功能:

 var arr = [ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 3, 3, 4, 5, 6, 7, 8, 9, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12], ]; function sortNumericArrays(a, b){ var i, l = a.length > b.length ? a.length : b.length, result = 0; for(i = 0; i < l; i++){ if(undefined === a[i]){ result = -1; i = l; }else if(undefined === b[i]){ result = 1; i = l; }else if(a[i] !== b[i]){ result = a[i] - b[i]; i = l; } } return result; } console.log(arr.sort(sortNumericArrays)); 

您可以通過使用自然排序(通過點或任何您喜歡的其他字符將數字值連接起來)來模仿這一點。

 var list = [ [ 1, 2, 3, 4 ], [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 2 ], [ 1, 3, 4 ], [ 1, 3 ], [ 1, 4 ], [ 1 ], [ 2, 3, 4 ], [ 2, 3 ], [ 2, 4 ], [ 2 ], [ 3, 4 ], [ 3 ], [ 4 ] ]; function versionNumberSort(a, b) { return a.join('.').localeCompare(b.join('.')) } console.log(list.sort(versionNumberSort).map(l => l.join(', ')).join('\\n')); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 


這是使用浮點排序的簡寫方法。

注意:這是一個技巧,使用較大的列表可能會出現浮點精度錯誤。

 var list = [ [ 1, 2, 3, 4 ], [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 2 ], [ 1, 3, 4 ], [ 1, 3 ], [ 1, 4 ], [ 1 ], [ 2, 3, 4 ], [ 2, 3 ], [ 2, 4 ], [ 2 ], [ 3, 4 ], [ 3 ], [ 4 ] ]; function sortNumberArrays(a, b) { return parseFloat('0.' + a.join('')) - parseFloat('0.' + b.join('')); } console.log(list.sort(sortNumberArrays).map(l => l.join(', ')).join('\\n')); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 
 <!-- Desired result: [ [ 1 ] [ 1, 2 ] [ 1, 2, 3] [ 1, 2, 3, 4 ] [ 1, 2, 4] [ 1, 3 ] [ 1, 3, 4 ] [ 1, 4 ] [ 2 ] ... [ 4 ] ] --> 

暫無
暫無

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

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