使用 ES6 增加对象 属性 没有地图

Use ES6 to increment object property without map

问题

我不是真正的初学者,但这可能是一个初学者问题。我正在尝试增加 ES6 JavaScript 对象的计数 属性。这个最小代码示例的两个最成功的版本(因为它们给了我错误的信息,但没有错误)return "NaN" 或每个水果的数量为“1”属性。这看起来应该可行,但显然递增数字对象 属性 不是一个直观的概念。

所以,这就是我想要做的:

创建水果对象作为键以及它们出现的次数。结束对象看起来像这样:

fruitsObj[fruit].name
fruitsObj[fruit].count

所以 "apple":

fruitsObj.apple.name // apple
fruitsObj.apple.count // 4

但是,我收到的输出是:

{apple: {…}, pear: {…}, banana: {…}, orange: {…}, kumquat: {…}}
apple:{name: "apple", count: NaN}
banana:{name: "banana", count: NaN}
kumquat:{name: "kumquat", count: NaN}
orange:{name: "orange", count: NaN}
pear:{name: "pear", count: NaN}
__proto__: Object

在版本 2 中,我尝试进行存在性和类型检查,但无济于事。我得到“1”作为每个计数的唯一值:

{apple: {…}, pear: {…}, banana: {…}, orange: {…}, kumquat: {…}}
apple:{name: "apple", count: 1}
banana:{name: "banana", count: 1}
kumquat:{name: "kumquat", count: 1}
orange:{name: "orange", count: 1}
pear:{name: "pear", count: 1}
__proto__: Object

我不确定我做错了什么。

我的代码

版本 1:

// Declare an array of fruits
var fruitsArr = ['apple', 'pear', 'apple', 'banana', 'orange', 'kumquat', 'orange', 'apple', 'apple', 'orange'];

var fruitsObj = {};

// Loop through each fruit storing name and count.
fruitsArr.forEach(function(fruit, i) {
 
 // Create each named-fruit property in object as a sub-object.
 fruitsObj[fruit] = {};
 
 fruitsObj[fruit].name = fruit;
 
 // FAILS with NaN!
 fruitsObj[fruit].count = ++fruitsObj[fruit].count;
 
});

console.log(fruitsObj);

版本 2:

// Declare an array of fruits
var fruitsArr = ['apple', 'pear', 'apple', 'banana', 'orange', 'kumquat', 'orange', 'apple', 'apple', 'orange'];

var fruitsObj = {};

// Loop through each fruit storing name and count.
fruitsArr.forEach(function(fruit, i) {
 
 // Create each named-fruit property in object as a sub-object.
 fruitsObj[fruit] = {};
 
 fruitsObj[fruit].name = fruit;

 // if fruit count exists and is greater than zero
 if (fruitsObj[fruit].count != undefined && fruitsObj[fruit].count > 0) {
  // increment it
  fruitsObj[fruit].count++;
 } else {
  // set it to one
  fruitsObj[fruit].count = 1;
 } 
 
});

console.log(fruitsObj);

我查阅的链接

我查看了一堆让我陷入困境的帖子和链接。即便如此,none 他们清楚地解决了我能说出的问题。

我的问题

  1. 为什么我的计数器没有增加,而是 return 增加 'NaN'?
  2. 在赋值之前,是否有一些特殊的方法可以将对象 属性 声明为数字?
  3. 我对完成这项工作的理解缺少什么?如何增加我的对象计数属性?

当水果对象不存在时,用count: 0初始化水果的对象,然后对每个同名水果的计数加1:

// Declare an array of fruits
var fruitsArr = ['apple', 'pear', 'apple', 'banana', 'orange', 'kumquat', 'orange', 'apple', 'apple', 'orange'];

var fruitsObj = {};

// Loop through each fruit storing name and count.
fruitsArr.forEach(function(fruit) {
  // if the object lacks a [fruit] property
  if(!fruitsObj[fruit]) {
    // create a new [fruit] object, with the name and count: 0
    fruitsObj[fruit] = { 
      name: fruit,
      count: 0
    };
  }
 
  // increment the count of the [fruit] object
  fruitsObj[fruit].count++;
});

console.log(fruitsObj);

Why is my counter not incrementing, but instead returning 'NaN'?

因为您试图在第一种情况下增加未定义的 属性。排队

fruitsObj[fruit].count = ++fruitsObj[fruit].count;

fruitsObj[fruit].count 未定义,因为您从未为其分配任何数值。您在第二个代码块中更正了这个问题。

What am I missing in my understanding to make this work? How can I increment my object count properties?

第二个代码的问题是这一行

// Create each named-fruit property in object as a sub-object.
    fruitsObj[fruit] = {};

您在每次迭代中都分配了一个新对象。所以即使这个水果是第二次来,当你分配一个新对象时,新对象会覆盖以前的值。你可以通过检查这个对象是否已经存在来消除它,就像这样

// Declare an array of fruits
    var fruitsArr = ['apple', 'pear', 'apple', 'banana', 'orange', 'kumquat', 'orange', 'apple', 'apple', 'orange'];
    
    var fruitsObj = {};
    
    // Loop through each fruit storing name and count.
    fruitsArr.forEach(function(fruit, i) {
     
     // Create a fruit object only if it does not exist already.
        if (!fruitsObj[fruit]) {
        fruitsObj[fruit] = {};
        }
     
     fruitsObj[fruit].name = fruit;
    
     // if fruit count exists and is greater than zero
     if (fruitsObj[fruit].count != undefined && fruitsObj[fruit].count > 0) 
        {
      // increment it
      fruitsObj[fruit].count++;
     } else {
      // set it to one
      fruitsObj[fruit].count = 1;
     } 
     
    });
    
    console.log(fruitsObj);

在您的 forEach 循环中,只尝试这两行:

if(fruitObj[fruit]) fruitObj[fruit].count+=1;
else fruitObj[fruit] = {name: fruit, count: 1};

这是实例化还是递增,取决于之前的实例化。您不能增加未实例化的值,并且在您的第二个版本中,您每次(无条件)实例化新的空对象。