【问题标题】:JavaScript Function - count the occurrences of a value in an array of objectsJavaScript 函数 - 计算对象数组中某个值的出现次数
【发布时间】:2020-01-20 03:22:15
【问题描述】:

我被分配了一项任务,但我一定错过了什么。提供的代码不是原始问题,而是类似的。我必须计算数组中有多少人年龄在 16 岁或以上。我玩过它,但我无法解决。请问,有人可以解释我做错了什么吗?

在任务中,我得到了一个对象数组:

var people = [{name:'Emma', age:15},{name:'Matt', age: 16}, {name:'Janet', age:17}]

我需要完成一个函数来计算有多少人年满 16 岁或以上。给出函数的开头(即function correctAge(people){ //Complete }

“示例代码”是我一直在玩的一些框架代码。 “不正确的尝试”是我的尝试,这是我不断返回的代码或其变体也是正确的......

请帮忙

不正确的尝试:

var people = [
  {name: "Emma", age: 15},
  {name: "Matt", age: 16},
  {name: "Tom", age: 17}
];

function correctAge(array) {
  // Complete the function to return how many people are age 16+
  var count = 0;

  for (let i = 0; i < array.length; i++) {
    var obj = array.length[i];
    for (prop in obj) {
      if (prop[obj] >= 16) {
        count++;
      }
    }
    return count;
  }
}

console.log(correctAge(people));

示例代码:

var people = [
  {name: "Emma", age: 15},
  {name: "Matt", age: 16},
  {name: "Tom", age: 17}
];

function correctAge(people) {
  // Complete the function to return how many people are age 16+
}

【问题讨论】:

  • 请在问题中添加代码并尝试作为文本。
  • 你不应该遍历对象中的所有属性,你应该使用obj.age
  • 将您的代码发布为纯文本,而不是图像。您可以使用Stack Snippets 创建可执行示例。

标签: javascript arrays javascript-objects


【解决方案1】:
people.filter(x=>{return x.age>=16}).length;

将上面的代码行添加到您的函数中。

【讨论】:

  • 嘿,谢谢。我确实尝试过,但没有被接受。我必须使用该功能。
  • 直接返回上面的代码,或者存入一个变量,在函数内部返回。它会起作用的。
  • 请注意,这也可以用更简单的形式使用:people.filter(x =&gt; x.age &gt;= 16).length
【解决方案2】:

遍历你的数组,检查元素匹配参数的属性并增加一个计数器。

下面的代码示例,名称和属性已更改以保护无辜者。

const cars = [
  { make: 'Nissan', country: 'Japan' },
  { make: 'Ford', country: 'USA' },
  { make: 'Chevy', country: 'USA' },
  { make: 'Volvo', country: 'Sweden' },
  { make: 'Mitsubishi', country: 'Japan' },
];

function fromCountry(cars, country) {
  let count = 0;
  for(let i = 0; i < cars.length; i++) {
    if (cars[i].country === country) {
      count++;
    }
  }
  return count;
}

const fromCountry2 = (cars, country) => cars.reduce((count, car) => {
  car.country === country && count++;
  return count;
}, 0);

console.log(fromCountry(cars, 'Japan')); // 2
console.log(fromCountry(cars, 'Sweden')); // 1
console.log(fromCountry(cars, 'USA')); // 2
console.log(fromCountry(cars, 'Canada')); // 0

console.log(fromCountry2(cars, 'Japan')); // 2
console.log(fromCountry2(cars, 'Sweden')); // 1
console.log(fromCountry2(cars, 'USA')); // 2
console.log(fromCountry2(cars, 'Canada')); // 0

【讨论】:

  • cars.reduce((count, car) =&gt; count + (car.country === country), 0) 也可以使用
【解决方案3】:

试试这个你会得到你的结果;

var people = [{name:'Emma', age:15},{name:'Matt', age: 16}, {name:'Janet', age:17}];

const correctAge = function(age) {
 return people.filter(x => x.age < age).length;
}

console.log(correctAge(16));

【讨论】:

    【解决方案4】:

    您需要使用索引来获取对象。

    obj = array[i];
    

    那么就可以直接取属性,不用循环所有属性。

    if (obj.age >= 16) {
        count++;
    }
    

    您可以将这两个部分放在一个检查中,而无需使用另一个变量 obj

    if (array[i].age >= 16) {
        count++;
    }
    

    .age 是对象的property accessor

    {
        name: 'Emma',
        age: 15       // <--
    }
    

    如果您喜欢单行方法,您可以减少数组并计算出现次数。

    return array.reduce((count, { age }) => count + (age >= 16), 0);
    

    【讨论】:

    • 谢谢。我已经尝试过了,但它不起作用,因为函数中没有定义“年龄”。
    • .age 在对象中。它在数据中给出。
    【解决方案5】:

    使用数组的filter方法会简单很多:

    function correctAge(people = [], age = 16){
    
        return people.filter( person => person.age > age ).length
    }
    

    【讨论】:

    • 谢谢。这很棒,对我有用。不知道我为什么要把它弄得这么复杂。
    【解决方案6】:

    Array.reduce() 是一个优雅的解决方案 -

    function correctAge(array) {
      return array.reduce((total, person) => {
          return person.age >= 16 ? ++total : total;
        }, 0)
    }
    

    对于问题中的示例,这将返回值 2。

    【讨论】:

      【解决方案7】:

      这里的大多数答案都集中在Array.filter()Array.reduce() 的使用上(我认为这是最合适的方法)。但是,我想指出如何修改您的“错误尝试”以使其真正起作用。以下是我采取的一些纠正措施:

      1. 去掉prop循环。这里你只关心age属性,所以不需要检查其他的props。 (prop[obj]其实是倒退了,反正应该是obj[prop]
      2. return count; 移到外部 for 循环之外。
      3. array.length[i] 替换为array[i].length 数组属性是一个整数,而不是数组或对象。

      var people = [
        {name: "Emma", age: 15},
        {name: "Matt", age: 16},
        {name: "Tom", age: 17}
      ];
      
      function correctAge(people) {
        // Complete the function to return how many people are age 16+
        var count = 0;
      
        for (let i = 0; i < people.length; i++) {
          var obj = people[i]; // <-- instead of array.length[i]
          if (obj.age >= 16) { // <-- obj.age instead of obj[prop]
            count++;
          }
        }
        return count; // <-- moved outside the loop
      }
      
      console.log(correctAge(people));

      现在,再次使用 Array.reduce(),这是一个很棒的聚合工具:

      var people = [
        {name: "Emma", age: 15},
        {name: "Matt", age: 16},
        {name: "Tom", age: 17}
      ];
      
      function correctAge(people) {
        // start at 0, then add 1 when obj.age >= 16, 0 otherwise
        return people.reduce(
          (acc, obj) => acc + (obj.age >= 16 ? 1 : 0), 0
        );
      }
      
      console.log(correctAge(people));

      Array.filter() 是最易读的方法,imo:

      var people = [
        {name: "Emma", age: 15},
        {name: "Matt", age: 16},
        {name: "Tom", age: 17}
      ];
      
      function correctAge(people) {
        return people.filter(obj => obj.age >= 16).length;
      }
      
      console.log(correctAge(people));

      ...最后,还有一些建议,这些建议可能不符合您当前的标准,但对于您未来的努力(尤其是对于更大的代码库)的可读性/可维护性而言,了解这些建议很重要:

      1. 我看到您在示例中使用了let,这意味着您可以访问const。我会鼓励你use const instead of let as much as possible。另外,因为constletvar (block-scoping) 的工作方式不同,我将完全停止使用var,以避免混淆。 const 也可以用在函数上以防止它们被替换。
      2. 遵循一致的编码风格也有助于提高可读性。如果您不了解它们,StandardAirbnb 之类的样式指南特别有用,因为它们指向推理和可用于执行这些规则的其他工具。 (例如,我对const 的看法最初来自 Airbnb)
      3. 正如函数式编程范例所鼓励的那样,immutability is also important。即使我们无法访问 JS 中的不可变对象(至少没有库或 Object.freeze() 的帮助),简单地将值视为不可变,作为一种习惯,也有同样的好处 - 而 const 经常让你半途而废防止重新分配。
      4. 命名很难,但值得努力。例如,person 将比 obj 更具描述性。此外,correctAge 本身的描述性还不够——如果没有找到函数并查看其定义,您将不知道“正确的年龄”是多少。对于这个例子来说这不是问题,因为它很小,但是,就像这些建议的其余部分一样,最好在像这样的小例子上养成良好的习惯,这样你以后就不需要考虑了。
      5. 使用数组/可迭代方法时,我认为最好定义回调而不是数组包装器。这使功能更加composable - 也就是说,您可以轻松混合/匹配它们。

      ...这导致了我的最终 sn-p:

      const people = [
        {name: 'Matt', age: 15},
        {name: 'Emma', age: 15},
        {name: 'Matt', age: 16},
        {name: 'Tom', age: 17},
        {name: 'Matt', age: 37}
      ]
      
      const personHasName = (person, name) => person.name === name
      const personIsOfAge = (person, age) => person.age >= age
      
      // Composition of personHasName and personIsOfAge
      const mattsOver16 = person =>
          personHasName(person, 'Matt') && personIsOfAge(person, 16)
      
      console.log(
        people.filter(mattsOver16).length
      )

      【讨论】:

        猜你喜欢
        • 2012-03-24
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多