【问题标题】:Pushing to an array inside an object推送到对象内的数组
【发布时间】:2017-09-26 02:59:20
【问题描述】:

我最近刚接触到 JS,并且一直在做一个练习,将人们从一系列记录 ancestry 中分类到他们所生活的世纪和年龄。这是来自ancestry 的示例元素:

{
name:   "Carolus Haverbeke"
sex:    "m"
born:   1832
died:   1905
father: "Carel Haverbeke"
mother: "Maria van Brussel"
}

这是我的尝试:

ancestry.forEach(function(person) {
  var ages = {};
  var century = Math.ceil(person.died / 100);

  if (century in ages) 
    ages[century].push(person.died - person.born);
  else
    ages[century] = person.died - person.born;
});

这是我试图存储在ages 中的一般格式,它将每个世纪映射到人们年龄的数组:

{
16: [24, 51, 16]
17: [73, 22]
18: [54, 65, 28]
}

我真的很困惑,因为这段代码只将ancestry 中的第一个人保存到ages。我想可能是因为我在forEach 内定义了ages,但是当我将var ages = {} 移到外面时,我得到了这个:

TypeError: ages[century].push is not a function (line 18)

有人可以帮忙解释一下发生了什么并且应该修复代码吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    tl;博士

    var ancestry = [{ ... }, { ... }, ...],
        ages = {};
    
    ancestry.forEach(function (person) {
        var century = Math.ceil(person.died / 100),
            age = person.died - person.born;
    
        !ages[century] && (ages[century] = []);
    
        ages[century].push(age);
    });
    
    console.log(ages);
    

    我们将描述您的代码以了解问题:

    假设我们有一个 ancestry 数组(这意味着 var ancestry = [{...}, {...}, ...] 是这种形式,每个项目看起来像这样:

    var ancestry = [{
        name: "Carolus Haverbeke",
        sex:  "m",
        born: 1832,
        died: 1905,
        father: "Carel Haverbeke",
        mother: "Maria van Brussel"
    }, {
        name: "Carolus Haverbeke",
        sex:  "m",
        born: 1722,
        died: 1805,
        father: "Carel Haverbeke",
        mother: "Maria van Brussel"
    }, {
        name: "Carolus Haverbeke",
        sex:  "m",
        born: 1666,
        died: 1705,
        father: "Carel Haverbeke",
        mother: "Maria van Brussel"
    }, {
        name: "Carolus Haverbeke",
        sex:  "m",
        born: 1622,
        died: 1715,
        father: "Carel Haverbeke",
        mother: "Maria van Brussel"
    }];
    

    使用不同的数据。

    要实现您想要的,请按照以下步骤操作:

    // Create your variable in the parent scope to allow variables to exist after the end of `forEach` method.
    var ages = {};
    
    // In the ancestry Array, we will loop on all items like `{ ... }`.
    ancestry.forEach(function (person) {
      // For each loop `person` will contain the current `{ ... }` item.
    
      // Because we want add this property to the existant object, we don't need a new object. And as you said,
      // 1. `ages` will be deleted in each loop because is defined into `forEach`
      // var ages = {};
    
          // We get the century of die.
      var century = Math.ceil(person.died / 100),
          // and age of die
          age = person.died - person.born;
    
      // now if the century property not exist, create a new array into to accept all centuries after.
      if (!ages[century]) {
          ages[century] = [];
      }
      // equivalent to `!ages[century] && (ages[century] = []);`
    
        // in all cases, just push the value to the end.
        ages[century].push(age);
    });
    
    // Still exist !
    console.log(ages); // Object {18: Array(2), 19: Array(1), 20: Array(1)}
    

    你的最终格式是你想要的:

    {
        18: [39, 93],
        19: [83],
        20: [73]
    }
    

    【讨论】:

      【解决方案2】:

      您需要将century 变量实例化为键值对(一种称为“关联数组”的数组)中的键,然后将ages 存储到该数组中的另一个数组中(记住century 是你的键和值是一个数组)。

      基本上,它是一个二维关联数组,因此您不妨只使用一个对象。

      所以它需要看起来像var ages = {16: {24, 51, 16}, 17: {73, 22}, 18: {54, 65, 28}};

      var ages = {16: {}, 17: {}, 18: {}}; 然后您可以递归地将这些值推送到相应键的数组中。

      键值对:Best way to store a key=>value array in JavaScript?

      多维关联数组(对象):Multi-dimensional associative arrays in javascript

      W3School(JavaScript 对象):https://www.w3schools.com/js/js_objects.asp

      您可以将年龄数组存储在一个对象中并通过键访问该数组(在您的情况下,您已声明为century)。

      如果是我,我会将person 设为一个对象,然后将每个人的birthdaydate-of-deathage-at-death 作为属性存储在数据库中。

      出于好奇,如果有人生活在两个不同的世纪,你会怎么做?我出生于 1987 年,现在是 2017 年,所以我是生活在 20 世纪还是 21 世纪?

      【讨论】:

        【解决方案3】:

        你需要在外面定义ages数组。

        你得到的错误是因为你没有将你的ages[century]初始化为array。因此它只会存储一个值。

        添加这一行

        ages[century] = []
        

        ages[century].push() 这样就可以正常工作了

        这是您需要在 if-else 中进行的更改

        if (ages[century]){
           ages[century].push(person.died - person.born);
        }
        else{
           ages[century] = []
           ages[century].push(person.died - person.born);
        }
        

        【讨论】:

          【解决方案4】:

          你需要像ages[century] = [person.died - person.born];这样在else语句中创建数组

              ancestry.forEach(function(person) {
                var ages = {};
                var century = Math.ceil(person.died / 100);
          
                if (century in ages) 
                  {
                  ages[century].push(person.died - person.born);
                      }
                else
                     {       
                  ages[century] = [person.died - person.born];
                     }
              });
          

          【讨论】:

          • 我正在尝试保存一系列年龄 - 您的代码意味着每次世纪发生时年龄都会被覆盖。
          猜你喜欢
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-20
          • 2019-04-08
          相关资源
          最近更新 更多