【问题标题】:nodejs map return nothing when if statement true当 if 语句为真时,nodejs map 不返回任何内容
【发布时间】:2020-09-12 00:00:22
【问题描述】:

所以我有以下代码

data.push(commands.map(
    command => {
        if (!command.devOnly) { return command.name; } // first condition
        if (command.devOnly && message.author.id != '3251268789058714880') {} // second condition
    },
).join('\n'));

如果第二个条件为真,则返回null,但是当我运行console.log(data) 时,所有第二个条件为真的命令都有一个空行。

有没有办法阻止第二个条件返回任何东西,而不是留下空白行

【问题讨论】:

    标签: node.js if-statement return


    【解决方案1】:

    .map() 是一对一的转换,因此输出数组中的元素数量将与输入数组完全相同。如果您不返回任何内容,则数组中的该元素将具有undefined 值(这是您不主动返回某些内容时的返回值)。

    要转换数组并消除某些元素,您不能使用.map()。您可以执行.filter().map(),首先过滤掉您不想要的项目,然后映射其他项目,或者您可以使用常规的for 循环并将项目推入您想要继续使用的输出数组中常规 for 循环迭代或 .reduce().forEach() 迭代。

    一个例子:

    const results = commands.filter(command => !command.devOnly).map(command => command.name);
    console.log(results);
    
    const results = [];
    for (let command of commands) {
        if (!command.devOnly) results.push(command.name);
    }
    console.log(results);
    

    请注意,您的第二个条件在您的代码示例中根本没有做任何事情,所以我不确定如何在这些示例中解释这一点。

    附:我经常希望 Javascript 有一个 .filterMap() 功能,可以让您返回 undefined 以将该值排除在结果之外 - 否则就像 .map() 一样工作。但是,它没有内置该功能。您可以自己构建。


    根据您的 cmets,您可以按以下两个条件进行过滤:

    const results = commands
       .filter(command => !command.devOnly || message.author.id === '3251268789058714880')
       .map(command => command.name);
    console.log(results);
    

    【讨论】:

    • 是否有办法修改.filter() 中的代码以包含我的第二个条件中的代码,如果message.author.id 是一个特定值,则它包含它?
    • @Nodejs-nerd - 你的第二个条件没有做任何事情。你想要那个条件做什么?当然,如果我知道该条件应该做什么,则可以修改.filter()。它需要在 if 之后的 {} 内进行一些操作。
    • 刚刚意识到它没有做任何事情,是测试的剩余部分。所以,如果命令是 devonly 并且 message.author.id 是一个值(我的 id)那么它应该添加它,如果它是 devonly 并且 message.author.id 不是我的 id 那么不要添加它
    • @Nodejs-nerd - 我在.filter() 的答案末尾添加了一个示例,其中包含两个条件。如果它是!command.devOnlymessage.author.id 是一个特定值,这将包括该项目。您显然可以修改该条件逻辑以适应您的任何目的。
    • 好的,我想我应该可以从这里进行更改。谢谢!
    【解决方案2】:

    你可以使用Array.reduce

    commands.reduce((prev,command)=>{
    
      if (!command.devOnly) 
         return [...prev,command.name]
      // this if, is useless but shows that you can use more conditions.
      if (command.devOnly && message.author.id != '3251268789058714880') 
         return prev
    
      // add more conditions as you need here
      return prev
    
    
    },[])
    

    另一种选择是通过 map 然后过滤未定义的值,或使用 for-loop 就像 jfriend00 在他的回答中解释的那样。他希望的filterMap()可以用Array.reduce实现

    【讨论】: