推送到对象内的数组

时间:2017-04-28 05:31:00

标签: javascript

我最近选择了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)

有人可以帮助解释发生了什么,代码应该修复吗?

4 个答案:

答案 0 :(得分:2)

你需要在else语句中创建数组,如 $user = $this->em->getRepository('OroUserBundle:User')->createQueryBuilder('u') ->select('u.username') ->innerJoin('u.groups','g') ->andWhere('g.name = :group') ->setParameter('group', 'Full-timer') ->getQuery(); $contacts = $this->em->getRepository('OroContactBundle:Contact')->createQueryBuilder('c') ->select('c') ->innerJoin('c.groups','g') ->andWhere('g.label = :group') ->andWhere('c.semester_contacted = :sem') ->setParameter('group', 'New One') ->setParameter('sem', '2017A') ->setMaxResults(1) ->getQuery();

ages[century] = [person.died - person.born];

答案 1 :(得分:2)

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 :(得分:1)

您需要在外部定义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);
}

答案 3 :(得分:1)

您需要将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世纪?