我最近才拿起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中。我以为可能是因为我在ages内定义了forEach,但是当我将var ages = {}移到外面时,我得到了:
TypeError: ages[century].push is not a function (line 18)
有人可以帮忙解释一下发生了什么,并且应该修复代码?

最佳答案

tl; dr

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]
}

关于javascript - 推送到对象内部的数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43672618/

10-13 06:18