Java 脚本创建按对象属性分组的新数组

Java script create new array grouped by object properties

我正在学习 Java 脚本并尝试根据对象的特定属性合并对象数组。

例如,我有以下数组,其中包含属性 a、b、c、pet 和 age 的对象。 如果 2 个对象的属性 a、b、c 相同,我想创建一个包含 pet 和 age 分组的新数组。 如果 a、b、c 中的任何属性不匹配,我想将它们作为新对象添加到我的输出数组中。

myArray = [
  {
    a: 'animal',
    b: 'white',
    c: true,  
    pet: 'dog1',
    age: 1  
  },
  {
    a: 'animal',
    b: 'white',
    c: true,
    pet: 'dog2',
    age: 2
  },
  {
    a: 'animal2',
    b: 'white',
    c: true,
    pet: 'cat1',
    age: 5
  },
  {
    a: 'animal2',
    b: 'black',
    c: false,
    pet: 'cat2',
    age: 1
  }
]

按属性 a、b、c 分组的输出数组。我的输出数组的第一个元素包含输入数组中对象 0,1 的组合值,因为它们具有与 a、b、c 相同的属性。剩余的作为单独的值添加,因为它们在一个属性中不同。

outputArray = [
    {
        a: 'animal',
        b: 'white',
        c: true,
        pets: [{pet:'dog1,age:1},{pet:dog2,age:2}]
    },
    {
        a: 'animal2',
        b: 'white',
        c: true,
        pets: [{pet: 'cat1', age:5}]
    },
    {
        a: 'animal2',
        b: 'black',
        c: false,
        pets:[{pet: 'cat2', age: 1}]
    }
 ]

接近尾声时,我想要一个所有元素按 属性 a、b、c 分组的数组。 有没有有效的方法呢?我尝试使用 for 循环进行暴力破解,但没有用。

TIA。

1) 您可以使用 Map and for..of

轻松获得结果

const myArray = [
  {
    a: "animal",
    b: "white",
    c: true,
    pet: "dog1",
    age: 1,
  },
  {
    a: "animal",
    b: "white",
    c: true,
    pet: "dog2",
    age: 2,
  },
  {
    a: "animal2",
    b: "white",
    c: true,
    pet: "cat1",
    age: 5,
  },
  {
    a: "animal2",
    b: "black",
    c: false,
    pet: "cat2",
    age: 1,
  },
];

const dict = new Map();
for (let { a, b, c, ...rest } of myArray) {
  const key = `${a}|${b}|${c}`;
  !dict.has(key)
    ? dict.set(key, { a, b, c, pets: [{ ...rest }] })
    : dict.get(key).pets.push(rest);
}

const result = [...dict.values()];
console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; 

2) 您也可以使用 Object.values and reduce

获得相同的结果

const myArray = [
  {
    a: "animal",
    b: "white",
    c: true,
    pet: "dog1",
    age: 1,
  },
  {
    a: "animal",
    b: "white",
    c: true,
    pet: "dog2",
    age: 2,
  },
  {
    a: "animal2",
    b: "white",
    c: true,
    pet: "cat1",
    age: 5,
  },
  {
    a: "animal2",
    b: "black",
    c: false,
    pet: "cat2",
    age: 1,
  },
];

const result = Object.values(
  myArray.reduce((dict, { a, b, c, ...rest }) => {
    const key = `${a}|${b}|${c}`;
    !dict[key]
      ? (dict[key] = { a, b, c, pets: [{ ...rest }] })
      : dict[key].pets.push(rest);
    return dict;
  }, {})
);

console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0;