【问题标题】:Separate and group all objects into a new array based on a property [closed]根据属性将所有对象分离并分组到一个新数组中[关闭]
【发布时间】:2020-01-13 08:52:32
【问题描述】:

我有一个对象数组,我需要将其拆分为 2 个数组,一个包含与特定属性匹配的所有对象,另一个包含其余对象的数组。

例如,这是一个示例数组:

const fruits = [
    {name:"orange", qty: 1},
    {name:"orange", qty: 2},
    {name:"banana", qty: 4},
    {name:"apple", qty: 6},
    {name:"kiwi", qty: 3},
    {name:"apple", qty: 2}
];

我需要做的是将所有对象与名称 apple 组合到一个数组中,其余的到另一个数组中。

预期:

const fruits1 = [
    {name:"orange", qty: 1},
    {name:"orange", qty: 2},
    {name:"banana", qty: 4},
    {name:"kiwi", qty: 3},
];


const fruits2 = [
    {name:"apple", qty: 6},
    {name:"apple", qty: 2}
];

我可以使用过滤器来做到这一点,但是我必须循环两次水果。有没有更有效的方法?

【问题讨论】:

  • "使用过滤器,...我已经循环了两次水果"?那个怎么样?你能展示你的过滤器循环吗?
  • 使用简单的循环。如果名称是“apple”,则将其添加到fruits2 数组,否则添加到fruits1 数组?

标签: javascript arrays loops object grouping


【解决方案1】:

您可以创建一个partition 函数,根据谓词将项目分成两个数组。使用Array.reduce() 迭代数组,并将谓词应用于每个项目。谓词应该返回一个布尔值。将布尔结果转换为数字将为false 提供0,为true 提供1。使用数字作为子数组的索引来推送项目。您可以使用解构将结果分配给fruit1fruit2

const partition = (predicate, arr) => arr.reduce((r, o) => {
  r[+predicate(o)].push(o);
  
  return r;
}, [[], []]);

const fruits = [{"name":"orange","qty":1},{"name":"orange","qty":2},{"name":"banana","qty":4},{"name":"apple","qty":6},{"name":"kiwi","qty":3},{"name":"apple","qty":2}];

const [fruits1, fruits2] = partition(o => o.name === 'apple', fruits);

console.log(fruits1);
console.log(fruits2);

【讨论】:

    【解决方案2】:

    它的功能较少,但您可以push 到一个或另一个数组,具体取决于name

    const fruits = [
        {name:"orange", qty: 1},
        {name:"orange", qty: 2},
        {name:"banana", qty: 4},
        {name:"apple", qty: 6},
        {name:"kiwi", qty: 3},
        {name:"apple", qty: 2}
    ];
    
    const apples = [];
    const others = [];
    for (const fruit of fruits) {
      (fruit.name === 'apple' ? apples : others).push(fruit);
    }
    console.log(apples);

    如果你必须使用数组方法而不改变外部变量,你可以使用reduce一次组合成两个数组,但它看起来不那么可读:

    const fruits = [
        {name:"orange", qty: 1},
        {name:"orange", qty: 2},
        {name:"banana", qty: 4},
        {name:"apple", qty: 6},
        {name:"kiwi", qty: 3},
        {name:"apple", qty: 2}
    ];
    
    const [apples, others] = fruits.reduce((a, fruit) => {
      (fruit.name === 'apple' ? a[0] : a[1]).push(fruit);
      return a;
    }, [[], []]);
    console.log(apples);
    console.log(others);

    【讨论】:

      【解决方案3】:

      您可以使用forEach()。您甚至可以使用 filter() 数组函数,但为此您需要使用该 filter() 两次。因此,使用单个循环将复杂性降至最低:

      const fruits = [
          {name:"orange", qty: 1},
          {name:"orange", qty: 2},
          {name:"banana", qty: 4},
          {name:"apple", qty: 6},
          {name:"kiwi", qty: 3},
          {name:"apple", qty: 2}
      ];
      
      let fruits1 = [];
      let fruits2 = [];
      
      fruits.forEach((fruit) => {
        if(fruit.name === 'apple') {
          fruits2.push(fruit);
        } else {
          fruits1.push(fruit);
        }
      });
      
      console.log('fruits1', fruits1);
      console.log('fruits2', fruits2);

      【讨论】:

        猜你喜欢
        • 2015-03-14
        • 2018-07-30
        • 2019-05-05
        • 2016-04-20
        • 2022-01-18
        • 2021-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多