首页 > 解决方案 > 是否可以在 Javascript 中对嵌套数组使用闭包和递归方法

问题描述

我需要计算嵌套数组中的元音,我想用闭包来避免全局命名空间污染。这是我的代码:

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”之后停止,所以显然我的函数没有升级,我错过了一些东西。

我怎样才能做到这一点?

先感谢您。

标签: javascriptrecursionmultidimensional-arrayclosures

解决方案


你不需要嵌套函数,你可以声明一个递归函数并且仍然保持一切自包含。

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));


推荐阅读