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