輸入:
[1,2,[3,4,[5,6]]]
輸出:
[[1,2],[3,4],[5,6]]
這是解決方案:
function convert(a,res=[]) {
const group = (arr) => {
res.push(arr.slice(0,2));
arr.map((v) => Array.isArray(v) && group(v));
}
group(a);
return res;
}
console.log(convert([1,2,[3,4]])); // [[1,2],[3,4]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2],[3,4],[5,6]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2],[3,4],[5,6],[7,8]];
雖然問題解決了,但出于學習的目的,我一直想知道如何在沒有嵌套函式的情況下解決這個問題。我試圖重構代碼如下:
function convert(a,i=0,res=[]) {
return i >= a.length
? res
: convert(
a,
i 1,
Array.isArray(a[i]) ? [...res,a.slice(0,2)] : res
)
}
console.log(convert([1,2,[3,4]])); // [[1,2]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2]]
如您所見,結果并不理想。我只是無法完全理解它。任何反饋和指示將不勝感激:)
更新:
這是涵蓋更多測驗用例的解決方案:
function convert(a,res=[]) {
return !a.length
? res
: convert(
a.filter(Array.isArray).flat(),
[...res,a.filter((v) => !Array.isArray(v))]
);
}
console.log(convert([1,2,[3,4]])); // [[1,2],[3,4]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2],[3,4],[5,6]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2],[3,4],[5,6],[7,8]];
console.log(convert([1,2,[5,6,[9,10],7,8],3,4])); // [[1,2,3,4],[5,6,7,8],[9,10]]
console.log(convert([1,5,5,[5,[1,2,1,1],5,5],5,[5]])); // [[1,5,5,5],[5,5,5,5],[1,2,1,1]]
console.log(convert([1,[2],1,[[2]],1,[[[2]]],1,[[[[2]]]]])); // [[1,1,1,1],[2],[2],[2],[2]]
uj5u.com熱心網友回復:
我不確定這是否是您的意思,但是您可以使用直接遞回呼叫,將每個結果傳播到前一個結果中。
const input = [1, 2, [3, 4, [5, 6]]];
function flatten(arr) {
const res = [[]];
for (const e of arr) {
Array.isArray(e) ? res.push(...flatten(e)) : res[0].push(e);
}
return res;
}
console.log(flatten(input));
即使任何級別的元素被嵌套級別拆分,并且對于任何給定級別上的可變數量的元素,這也有效。
const input = [1, 2, [4, [5, 6, [8, 9], 7]], 3];
// [[ 1, 2, 3 ], [ 4 ], [ 5, 6, 7 ], [ 8, 9 ]]
function flatten(arr) {
const res = [[]];
for (const e of arr) {
Array.isArray(e) ? res.push(...flatten(e)) : res[0].push(e);
}
return res;
}
console.log(flatten(input));
編輯
為了適應注釋中提出的附加條件,但保持直接遞回而不將累加器傳遞給以后的呼叫,我可能會執行以下操作。
function flatten(arr) {
const level = [], nested = [];
for (const e of arr) {
Array.isArray(e) ? nested.push(...e) : level.push(e);
}
return [level, ...(nested.length ? flatten(nested) : [])]
}
console.log(flatten([1, 2, [3, 4, [5, 6]]]));
// [[ 1, 2 ], [ 3, 4 ], [ 5, 6 ]]
console.log(flatten([1, 2, [4, [5, 6, [8, 9], 7]], 3]));
// [[ 1, 2, 3 ], [ 4 ], [ 5, 6, 7 ], [ 8, 9 ]]
console.log(flatten([1, [2], 1, [[2]], 1, [[[2]]], 1, [[[[2]]]]]));
// [[ 1, 1, 1, 1 ], [ 2 ], [ 2 ], [ 2 ], [ 2 ]]
console.log(flatten([1, 5, 5, [5, [1, 2, 1, 1], 5, 5], 5, [5]]));
// [[ 1, 5, 5, 5 ], [ 5, 5, 5, 5 ], [ 1, 2, 1, 1 ]]
uj5u.com熱心網友回復:
我認為您更新的演算法很好。
不過,使用可重用的實用程式函式可能更容易表達。我通常有一個partition函式,它接受一個謂詞函式并回傳一個函式,它將一個陣列分成兩個子陣列,謂詞回傳的子陣列和謂詞回傳的子true陣列false。
使用它,這變得相當簡單:
const partition = (pred) => (xs) =>
xs .reduce (([t, f], x) => pred (x) ? [t .concat (x), f]: [t, f .concat (x)], [[], []])
const convert = (xs, [rest, first] = partition (Array .isArray) (xs)) =>
xs .length == 0 ? [] : [first, ...convert (rest)]
console.log (convert ([1, 2, [3, 4]])) //=> [[1, 2], [3, 4]]
console.log (convert ([1, 2, [3, 4, [5, 6]]])) //=> [[1, 2], [3, 4], [5, 6]]
console.log (convert ([1, 2, [3, 4, [5, 6, [7, 8]]]])) //=> [[1, 2], [3, 4], [5, 6], [7, 8]]
console.log (convert ([1, 2, [5, 6, [9, 10], 7, 8], 3, 4])) //=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
console.log (convert ([1, 5, 5, [5, [1, 2, 1, 1], 5, 5], 5, [5]])) //=> [[1, 5, 5, 5], [5, 5, 5, 5], [1, 2, 1, 1]]
console.log (convert ([1, [2], 1, [[2]], 1, [[[2]]], 1, [[[[2]]]]])) //=> [[1, 1, 1, 1], [2], [2], [2], [2]]
.as-console-wrapper {max-height: 100% !important; top: 0}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/520664.html
上一篇:如果直到我從reactjs中的回應中恢復資料,如何呼叫apitwise/不止一次
下一篇:錯誤:在實體化`<std::iter::Filter<std::iter::Sk...]>::{closure#0}]>::{closure#0}]>`時達到遞回限制
