我需要計算嵌套陣列中的元音,我想用閉包來做,以避免全域命名空間污染。這是我的代碼:
let nestedArr = [
"Elie",
["Matt", ["Tim"]],
["Colt", ["Whiskey", ["Janey"], "Tom"]],
"Lorien"
];
function countVowels() {
let vowelsCount = 0;
let vowels = ['a', 'e', 'i', 'o', 'u'];
return function foo(arr) {
for (let i = 0; i < arr.length; i ) {
if (typeof arr[i] === 'string') {
for (let letter of arr[i]) {
if (vowels.includes(letter.toLowerCase())) {
vowelsCount ;
}
}
} else {
return foo(arr[i]);
}
}
return vowelsCount;
}
}
const counter = countVowels();
console.log(counter(nestedArr));
我希望元音的數量正確,但得到 5。我嘗試除錯并看到它只是在最深的子陣列“Tim”之后停止,所以顯然我的函式沒有升級,我錯過了一些東西。
我怎樣才能做到這一點?
先感謝您。
uj5u.com熱心網友回復:
如果您只是更改,您的功能就可以正常作業
return foo(arr[i]);
到:
foo(arr[i]);
您需要讓整個回圈運行(顯然),回傳使它更早停止。
let nestedArr = [
"Elie",
["Matt", ["Tim"]],
["Colt", ["Whiskey", ["Janey"], "Tom"]],
"Lorien"
];
function countVowels() {
let vowelsCount = 0;
let vowels = ['a', 'e', 'i', 'o', 'u'];
return function foo(arr) {
for (let i = 0; i < arr.length; i ) {
if (typeof arr[i] === 'string') {
for (let letter of arr[i]) {
if (vowels.includes(letter.toLowerCase())) {
vowelsCount ;
}
}
} else {
foo(arr[i]);
}
}
return vowelsCount;
}
}
const counter = countVowels();
console.log(counter(nestedArr));
uj5u.com熱心網友回復:
您不需要嵌套函式,您可以宣告單個遞回函式并仍然保持所有內容自包含。
const countVowels = (arr) => {
const vowels = ['a', 'e', 'i', 'o', 'u'];
const vowel_count = (s) => [...s].filter((c) => vowels.includes(c.toLowerCase())).length;
let vowels_total = 0;
for (const e of arr) {
vowels_total = Array.isArray(e) ? countVowels(e) : vowel_count(e);
}
return vowels_total;
};
const nestedArr = ['Elie', ['Matt', ['Tim']], ['Colt', ['Whiskey', ['Janey'], 'Tom']], 'Lorien'];
console.log(countVowels(nestedArr));
或者,使用Array#flat()(to Infinity)
const countVowels = (
(v) => (arr) =>
[...arr.flat(Infinity).join('')].filter((c) => v.includes(c.toLowerCase())).length
)(['a', 'e', 'i', 'o', 'u']);
const nestedArr = ['Elie', ['Matt', ['Tim']], ['Colt', ['Whiskey', ['Janey'], 'Tom']], 'Lorien'];
console.log(countVowels(nestedArr));
uj5u.com熱心網友回復:
let nestedArr = [
'Elie',
['Matt', ['Tim']],
['Colt', ['Whiskey', ['Janey'], 'Tom']],
'Lorien',
];
function countVowels(str) {
return str.match(/['a', 'e', 'i', 'o', 'u']/gi)?.length || 0;
}
function vowelsAmount(arr) {
return arr.reduce((accumulator, currentElement) => {
return Array.isArray(currentElement)
? (accumulator = vowelsAmount(currentElement))
: (accumulator = countVowels(currentElement));
}, 0);
}
console.log(vowelsAmount(nestedArr));
uj5u.com熱心網友回復:
這聽起來像是學習遞回的練習。如果是這樣,我讓您在這里使用其他精細的遞回答案。
但是一個簡單的替代方法是注意toString陣列的格式,并意識到我們可以簡單地將測驗應用于其結果,留下一些非常簡單的代碼:
const countVowels = (a) =>
[... a .toString () .toLowerCase ()] .filter (c => 'aeiou' .includes (c)) .length
const nestedArr = ['Elie', ['Matt', ['Tim']], ['Colt', ['Whiskey', ['Janey'], 'Tom']], 'Lorien']
console .log (countVowels (nestedArr))
uj5u.com熱心網友回復:
遞回是一種函式式遺產,因此以函式式風格使用它會產生最好的結果。這意味著避免諸如突變、變數重新分配和其他副作用之類的事情。這是我們可以使用型別分析和歸納推理重寫程式的一種方法
細繩
- 如果輸入
t少于一個字符,則沒有什么可計算的。回傳空和,0。 - (歸納)
t至少有 1 個字符。如果第一個字符是元音,則將其轉換為 1,否則為 0,并將其添加到子問題的結果中。
大批
- 如果輸入的
t元素少于一個,則沒有什么可計算的。回傳空和,0 - (inductive)
t至少有一個元素。計算第一個元素的元音并將其添加到子問題的結果中。
任何其他型別
- 如果輸入
t既不是字串也不是陣列,則拋出錯誤以通知呼叫者我們無法計算該輸入型別的元音。
function countVowels (t) {
switch (t?.constructor) {
case String:
if (t.length < 1)
return 0 // 1
else
return isVowel(t[0]) countVowels(t.slice(1)) // 2
case Array:
if (t.length < 1)
return 0 // 1
else
return countVowels(t[0]) countVowels(t.slice(1)) // 2
default:
throw Error(`cannot count input type: {t?.constructor}`)
}
}
function isVowel (t) {
switch (t.toLowerCase()) {
case "a":
case "e":
case "i":
case "o":
case "u":
return true
default:
return false
}
}
const nestedArr =
['Elie', ['Matt', ['Tim']], ['Colt', ['Whiskey', ['Janey'], 'Tom']], 'Lorien']
console.log(countVowels(nestedArr))
14
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/326810.html
標籤:javascript 递归 多维数组 关闭
上一篇:提高python中的遞回效率
