【问题标题】:Why am I getting NaN and How do I get the expected output?为什么我得到 NaN 以及如何获得预期的输出?
【发布时间】:2021-10-26 14:12:21
【问题描述】:

我是 JS 新手。我想跟踪数组中重复对象的数量,在另一个对象中,所以我决定编写一个函数。例如:考虑下面的对象。

const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];

我想跟踪上面数组中重复对象的数量,所以我写了下面的函数。

function calcDuplicates(fruitObj) {
  const duplicates = {};
  for (let i of fruitObj) {
    duplicates[`${i.name}`] !== "undefined"
      ? (duplicates[`${i.name}`] += 1)
      : (duplicates[`${i.name}`] = 1);
  }
  return duplicates;
}

我得到的输出是:

{orange: NaN, apple: NaN, banana: NaN}

(预期输出) 我想要的输出是:

{orange: 2, apple: 1, banana: 1}

如何获得预期的输出?我做错了什么?

【问题讨论】:

  • 但是noOfItems 是未定义的?代码应该会因错误noOfItems is undefined 而崩溃
  • 因为duplicates['${i.name}']一开始是未定义的,当你将1添加到它时,它会给你NaN,导致undefined + 1 => NaN
  • duplicates[`${i.name}`]duplicates[i.name] 相同
  • @JeremyThille 很抱歉,在提问时,我将noOfItems 重命名为duplicates 并忘记在返回时更改它,我已经更正了。
  • @AdilBimzagh duplicates[i.name] 在第 8 行初始化为 1,如果未定义

标签: javascript arrays object duplicates


【解决方案1】:

您的错误是针对"undefined"(单词)而不是undefined(未定义值)进行测试:

const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];

function calcDuplicates(fruitObj) {
  const duplicates = {};
  for (let i of fruitObj) {
    duplicates[i.name] !== undefined
      ? (duplicates[i.name] += 1)
      : (duplicates[i.name] = 1);
  }
  return duplicates;
}

console.log( calcDuplicates(fruits) );

【讨论】:

    【解决方案2】:

    在条件中使用原始值undefined代替字符串"undefined"

    duplicates[`${i.name}`] !== undefined
    

    const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
    
    function calcDuplicates(fruitObj) {
      const duplicates = {};
      for (let i of fruitObj) {
        duplicates[`${i.name}`] !== undefined
          ? (duplicates[`${i.name}`] += 1)
          : (duplicates[`${i.name}`] = 1);
      }
      return duplicates;
    }
    console.log(calcDuplicates(fruits))

    【讨论】:

      【解决方案3】:
      1. 属性名称无需使用字符串文字。 i.name 就足够了。

      2. 您检查的是“未定义”而不是 undefined。但是,真的,没有必要这样做。只需检查对象属性是否存在。

      const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
      
      function calcDuplicates(fruitObj) {
        const duplicates = {};
        for (let i of fruitObj) {
          duplicates[i.name]
            ? duplicates[i.name] += 1
            : duplicates[i.name] = 1;
        }
        return duplicates;
      }
      
      console.log(calcDuplicates(fruits));

      【讨论】:

        【解决方案4】:

        只需从 undefined 中删除双引号 "

        const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
        
        function calcDuplicates(fruitObj) {
          const duplicates = {};
          for (let i of fruitObj) {
            duplicates[`${i.name}`] !== undefined
              ? (duplicates[`${i.name}`] += 1)
              : (duplicates[`${i.name}`] = 1);
          }
          return duplicates;
        }
        
        console.log( calcDuplicates(fruits) );

        【讨论】:

          【解决方案5】:

          这是因为您的条件应该针对undefined 进行测试,而不是包含'undefined' 的字符串。

          const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
          
          function calcDuplicates(fruitObj) {
            const duplicates = {};
            for (let i of fruitObj) {
              duplicates[`${i.name}`] !== undefined
                ? (duplicates[`${i.name}`] += 1)
                : (duplicates[`${i.name}`] = 1);
            }
            return duplicates;
          }
          
          console.log( calcDuplicates(fruits) );

          我就是这样写的:

          const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
          
          function calcDuplicates(fruitObj) {
            const duplicates = {};
            for (let i of fruitObj) {
              duplicates[i.name] = (duplicates[i.name] || 0) + 1
            }
            return duplicates;
          }
          
          console.log( calcDuplicates(fruits) );

          几乎相同的东西,使用reduce 和解构map

          const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
          
          const calcDuplicates = o => o
            .map(({ name }) => name)
            .reduce((a, b) => ({ ...a, [b]: (a[b] || 0) + 1 }), {})
          
          console.log( calcDuplicates(fruits) );

          【讨论】:

            【解决方案6】:

            这可以通过reduce 和对象解构来实现,如下所示:

            const fruits = [{name: 'orange'}, {name: 'orange'}, {name: 'apple'}, {name: 'banana'}];
            
            
            const duplicates = fruits.reduce( (acc,{name}) => {
              if (!acc[name]) acc[name] = 0 ; 
              acc[name]++;
              return acc;
            },{});
            
            console.log(duplicates);

            【讨论】:

            • 感谢@sivaraj-s 的编辑,但这改变了答案太多。你能考虑用你的想法来回答这个问题吗?我会赞成!
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-23
            • 1970-01-01
            • 1970-01-01
            • 2022-04-02
            • 1970-01-01
            • 2017-06-22
            相关资源
            最近更新 更多