Используйте метод уменьшения для суммирования значений в массиве объектов и поиска дубликатов — JS

#javascript #arrays #object

Вопрос:

У меня есть массив объектов:

 const fruits = [{
    type: oranges,
    amount: 10
  },
  {
    type: apples,
    amount: 0,
  }, {
    type: oranges,
    amount: 5
  }
]
 

Мне нужно сделать следующее:

  • суммируйте фрукты, если они одинаковые (например, суммируйте апельсины: {тип: апельсины, количество: 15})
  • добавьте новую пару ключ-значение в объект, в зависимости от того, сколько раз она присутствует в массиве (например, апельсины присутствуют два раза: {типы: апельсины, количество: 15, количество: 2} и яблоки присутствуют один раз {типы: яблоки, количество: 0, количество: 1} )

Поэтому моя цель-иметь что-то подобное:

 const fruits = [{
    type: oranges,
    amount: 15,
    count: 2
  },
  {
    type: apples,
    amount: 0,
    count: 1
  }
]
 

Я обнаружил, что метод сокращения-хороший способ достичь этого. Я работаю со следующим кодом (это должно суммировать сумму), но что бы я ни пытался, я не получаю результата. Я просто получаю новое значение ключа {…, метки: NaN}-так что, может быть, есть лучший подход:

 const fruits = [{
    type: "oranges",
    amount: 10
  },
  {
    type: "apples",
    amount: 0,
  }, {
    type: "oranges",
    amount: 5
  }
]

const endresult = Object.values(fruits.reduce((value, object) => {
  if (value[object.type]) {
    ['marks'].forEach(key => value[object.type][key] = value[object.type][key]   object[key]);
  } else {
    value[object.type] = { ...object
    };
  }
  return value;
}, {}));

console.log(endresult) 

Я не уверен, что я делаю неправильно, и как я могу добавить новую пару ключ-значение, чтобы подсчитать, сколько раз объект присутствует в массиве? Может ли кто-нибудь указать мне правильное направление? Спасибо!

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

1. undefined 5 == NaN

Ответ №1:

Ваш код выглядит более сложным, чем требуется. Где-то вы должны добавлять an undefined к числу и, следовательно, получать NaN (не число).

Также :

  1. вы не инициализируете count свойство.
  2. вы не добавляете amount и count в условие if.

Внесите несколько изменений в сам код, это можно исправить:

 const fruits = [{
    type: "oranges",
    amount: 10
  },
  {
    type: "apples",
    amount: 0,
  }, {
    type: "oranges",
    amount: 5
  }
]

const endresult = Object.values(fruits.reduce((value, object) => {
  if (value[object.type]) {
    value[object.type].amount  = object.amount; 
    value[object.type].count  ;

} else {
    value[object.type] = { ...object , count : 1
    };
  }
  return value;
}, {}));

console.log(endresult) 

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

1. Спасибо за ваш ответ. В настоящее время я пробую это и вернусь к вам, как только закончу

Ответ №2:

Вы можете легко достичь результата, используя Map, reduce и Array.from

 const fruits = [
  {
    type: "oranges",
    amount: 10,
  },
  {
    type: "apples",
    amount: 0,
  },
  {
    type: "oranges",
    amount: 5,
  },
];

const endresult = Array.from(
  fruits
    .reduce((map, curr) => {
      if (!map.has(curr.type)) map.set(curr.type, { ...curr, count: 1 });
      else {
        map.get(curr.type).amount  = curr.amount;
        map.get(curr.type).count  ;
      }
      return map;
    }, new Map())
    .values()
);

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

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

1. Спасибо. Это определенно новый подход для меня. Я новичок в разработке, поэтому мне придется подробно изучить его, чтобы понять код.

Ответ №3:

Это сокращение работает лучше

 const fruits = [{ type: "oranges", amount: 10 }, { type: "apples", amount: 0}, { type: "oranges", amount: 5 }]

const endresult = fruits.reduce((acc,fruit) => {
  acc[fruit.type] = acc[fruit.type]  || fruit;
  const theFruit = acc[fruit.type]
  theFruit.count = !!theFruit.count ? theFruit.count : 0;
  theFruit.count  
  theFruit.amount  = fruit.amount 
  return acc;
}, {});

console.log(Object.values(endresult))