我正在努力使用 Javascript 如何找到一個深度為 n 的陣列源的所有組合,這些組合被分成多個部分(下面的示例中為 0、1 和 2)。我想以每個可能的組合結束 - 每個回傳的陣列都應該包含一個且每個組中的一個值。我已將解決方案硬編碼為 4 個級別,但需要更大的靈活性 - 遞回提供的靈活性。我查看了很多 的 可能 遞回 的解決方案,而我了解那些作業,我只是無法弄清楚如何將這個特定的源資料得到的作業。
sourceArr=[
[0,60,100]
,[0,60,200]
,[0,66,300]
,[1,69,500]
,[2,70,600]
,[2,70,700]
,[2,77,800]
,[2,77,900]
]
預期回傳值...
[
[{60,100],{69,500},{70,600}]
,[{60,100],{69,500},{70,700}]
,[{60,100],{69,500},{77,800}]
,[{60,100],{69,500},{77,900}]
,[{60,200],{69,500},{70,600}]
,[{60,200],{69,500},{70,700}]
,[{60,200],{69,500},{77,800}]
,[{60,200],{69,500},{77,900}]
,[{66,300],{69,500},{70,600}]
,[{66,300],{69,500},{70,700}]
,[{66,300],{69,500},{77,800}]
,[{66,300],{69,500},{77,900}]
]
uj5u.com熱心網友回復:
本質上,這是一個笛卡爾積問題。但是您必須先了解它,因為您沒有要在單獨陣列中分組的元素。因此,首先,您需要按陣列的第一個元素對陣列進行分組,然后去掉第一個元素。
如果我們使用一些簡單的實用函式,我們可以撰寫一個簡單的版本,如下所示:
const combine = pipe (
group (head),
map (map (tail)),
cartesian
)
在這里,我們pipe將許多函式放在一起,創建了一個接受一些輸入的新函式,將其發送給第一個函式,然后將該函式的輸出發送給第二個函式,將其輸出發送給第三個函式,依此類推,回傳最終輸出。
我們在這個管道中group提供的第一個函式是根據head應用于每個的函式的結果提供給陣列的元素(它只回傳陣列的第一個元素。)這將給我們留下這樣的結構:
[
[[0, 60, 100], [0, 60, 200], [0, 66, 300],
[[1, 69, 500]],
[[2, 70, 600], [2, 70, 700], [2, 77, 800], [2, 77, 900]]
]
接下來我們使用嵌套map呼叫,傳遞tail給最里面的呼叫。 tail簡單地回傳除陣列第一個元素之外的所有內容。這會將上述內容轉換為
[
[[60, 100], [60, 200], [66, 300],
[[69, 500]],
[[70, 600], [70, 700], [77, 800], [77, 900]]
]
現在這是笛卡爾積函式使用的格式,所以我們包含一個簡單的cartesian函式,我們就完成了。
我們可以這樣寫這些助手:
// utility functions
const head = (xs) => xs [0]
const tail = (xs) => xs .slice (1)
const map = (fn) => (xs) =>
xs .map (x => fn (x))
const pipe = (...fns) => (x) =>
fns .reduce ((a, fn) => fn (a), x)
const group = (fn) => (xs) =>
Object .values (xs .reduce (
(a, x, _, __, k = fn (x)) => ((a[k] = [...(a[k] || []), x]), a),
{}
))
const cartesian = ([xs, ...xss]) =>
xs == undefined
? [[]]
: xs .flatMap (x => cartesian (xss) .map (ys => [x, ...ys]))
// main function
const combine = pipe (
group (head),
map (map (tail)),
cartesian
)
// sample data
const sourceArr = [[0, 60, 100], [0, 60, 200], [0, 66, 300], [1, 69, 500], [2, 70, 600], [2, 70, 700], [2, 77, 800], [2, 77, 900]]
// demo -- stringify is to avoid SO's id-ref presentation
console .log (JSON.stringify(combine (sourceArr), null, 4))
.as-console-wrapper {max-height: 100% !important; top: 0}
請注意,為了做到這一點,我使用了我閑置的函式。撰寫此答案所花的時間比撰寫代碼所花的時間要長得多。這就是維護可重用函式庫的優勢,您可以根據需要獲取這些函式。
這些特定的 API 類似于Ramda的設計。這并不奇怪,因為我是 Ramda 的創始人和維護者,但是我們自己創建和維護它們很簡單。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/371650.html
標籤:javascript 数组 递归 嵌套 嵌套循环
