Найдите элементы в массиве объектов, которые имеют одинаковые свойства, и создайте новый массив объектов

#javascript #arrays

Вопрос:

У меня есть массив объектов, подобных этому:

 arr = [
  { a: "dog", b: 8, c: "male", d: "big", e: 100 },
  { a: "dog1", b: 5, c: "female", d: "big", e: 200},
  { a: "dog2", b: 18, c: "female", d: "big", e: 350},
  { a: "dog2", b: 18, c: "female", d: "big", e: 350},
  { a: "dog", b: 3, c: "male", d: "big", e: 100 },
  { a: "dog", b: 8, c: "male", d: "big", e: 100 },
];
 

Я хочу создать новый массив , содержащий только свойство a и сумму e тех объектов , которые имеют одинаковые значения для b , c и d , так что у меня будет такой массив и:

 arr2 = [
  { a: "dog", e: 300 },
  { a: "dog2", e: 700},
];
 

Я уже пытался использовать map функцию внутри map функции , ища элементы , обладающие одинаковыми свойствами b , c а d затем помещая результат в arr2 , но он каждый раз выталкивает все объекты моего инициала arr .

Комментарии:

1. Вероятно, ищет reduce

Ответ №1:

Вы можете использовать Array.reduce для создания карты элементов массива, используя b,c и d в сочетании в качестве ключа.

Как только у нас будет эта карта, мы сможем использовать Object.values() ее для получения массива в качестве желаемого результата.

 arr = [
  { a: 'dog', b: 8, c: 'male', d: 'big', e: 100 },
  { a: 'dog1', b: 5, c: 'female', d: 'big', e: 200},
  { a: 'dog2', b: 18, c: 'female', d: 'big', e: 350},
  { a: 'dog2', b: 18, c: 'female', d: 'big', e: 350},
  { a: 'dog', b: 3, c: 'male', d: 'big', e: 100 },
  { a: 'dog', b: 8, c: 'male', d: 'big', e: 100 },
];

const result = Object.values(arr.reduce((acc, cur) => {
    // Create a key from b,c,d..
    const key = cur.b   cur.c   cur.d
    acc[key] = acc[key] || { a: cur.a, e: 0 };
    acc[key].e  = cur.e;
    return acc;
}, {}))

console.log('Result:', result); 

Ответ №2:

Универсальное решение для произвольного массива и ключей для суммирования

Если вы ищете решение vanilla JS (без lodash), вы можете придумать что-то, настраиваемое для произвольного свойства ключа группы и свойства для обобщения Array.prototype.reduce() :

  • постройте Map , имея желаемое свойство в качестве ключа;
  • приращение Map элементов на основе соответствующего ключа
  • поместите Map.prototype.values() это Map в массив
 const src = [
  { a: "dog", b: 8, c: "male", d: "big", e: 100 },
  { a: "dog1", b: 5, c: "female", d: "big", e: 200},
  { a: "dog2", b: 18, c: "female", d: "big", e: 350},
  { a: "dog2", b: 18, c: "female", d: "big", e: 350},
  { a: "dog", b: 3, c: "male", d: "big", e: 100 },
  { a: "dog", b: 8, c: "male", d: "big", e: 100 },
]

const summarizeValueByKey = (arr, key, val) => 
  [...arr
    .reduce((acc,{[key]: keyProp, [val]: valProp}) => {
      const group = acc.get(keyProp)
      group
        ? group[val]  = valProp
        : acc.set(keyProp, {[key]: keyProp, [val]: valProp})
      return acc
    }, new Map)
    .values()]
    
console.log(summarizeValueByKey(src, 'a', 'e'))