#javascript #arrays #object
Вопрос:
У меня есть этот список:
const list = [
{ name: 'AA', quantity: 1 },
{ name: 'AA', quantity: 1 },
{ name: 'BB', quantity: 1 },
{ name: 'CC', quantity: 1 },
{ name: 'CC', quantity: 2 },
]
И результат, который я ищу, должен выглядеть так:
const newlist = [
{ name: 'AA', quantity: 2 },
{ name: 'BB', quantity: 1 },
{ name: 'CC', quantity: 3 },
]
Этот код удаляет дубликаты, но я просто не могу понять, как увеличить количество при наличии дубликатов.
const setObj = new Set()
const result = list.reduce((acc, item) => {
if (!setObj.has(item.name)) {
setObj.add(item.name)
acc.push({ name: item.name, quantity: item.quantity })
}
// for (const iterator of list) {
// if (setObj.has(item.name)) {
// console.log('🚀 ~ file: Untitled-1 ~ line 15 ~ iterator', iterator)
// }
// }
console.log()
return acc
}, [])
Комментарии:
1. Когда вы толкаете объект, делайте
quantity: item.quantity * list.filter(i=> i.name === item.name).length
это .2. Попробовал, но получил { имя: ‘AA’, количество: 2}, {имя: ‘BB’, количество: 1}, { имя: ‘CC’, количество: 2 } cc должно быть 3
3. Ах, верно, потому
quantity
что это не обязательно 1 все время. Да, вам придется подвести итоги, и в этот момент вы могли бы с тем же успехомreduce
ответить за все это.
Ответ №1:
Вы можете использовать reduce
затем найти элемент в массиве результатов, если он не существует push
array
, в противном add
случае текущий элемент quantity
element
, который был найден в результате array
.
Код:
const list=[{name:"AA",quantity:1},{name:"AA",quantity:1},{name:"BB",quantity:1},{name:"CC",quantity:1},{name:"CC",quantity:2}];
const res = list.reduce((acc, e) => {
const found = acc.find(x => e.name === x.name)
found ? found.quantity = e.quantity : acc.push(e)
return acc
}, [])
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №2:
Несколько иной подход к объекту, который использует Object.values() для возврата результирующего массива
const list = [
{ name: 'AA', quantity: 1 },
{ name: 'AA', quantity: 1 },
{ name: 'BB', quantity: 1 },
{ name: 'CC', quantity: 1 },
{ name: 'CC', quantity: 2 },
]
const group = {};
list.forEach(e => {
const o = group[e.name] = group[e.name] || {...e, quantity: 0}
o.quantity = e.quantity
})
const res = Object.values(group)
console.log(res)
Комментарии:
1. я дам этот ответ как лучший, потому что я заметил, что количество для других также увеличивается после многократного использования.
Ответ №3:
Вы можете выполнить цикл, чтобы либо создать новую запись, либо увеличить текущую:
let newList = [];
list.forEach((e)=>{
let el=newList.find(n => n.name==e.name);
if (el) el.quantity =e.quantity;
else newList.push(e);
});
Комментарии:
1. Не используйте
map
при побочных эффектах.map
возвращает преобразованный массив. Используйте его или используйтеforEach
вместо него.2. да, спасибо, это то, что мне нужно, кроме того, я буду использовать forEach спасибо вам обоим
3. Зачем дважды использовать функцию find() для одного и того же элемента массива?
4. Потому что так было проще печатать :P. Я все исправил.
Ответ №4:
Наиболее очевидным решением здесь является использование объекта, потому что это то, что вы просите создать: вещь с уникальными именованными ключами.
const list = [
{ name: 'AA', quantity: 1 },
{ name: 'AA', quantity: 1 },
{ name: 'BB', quantity: 1 },
{ name: 'CC', quantity: 1 },
{ name: 'CC', quantity: 2 },
];
const filtered = list.reduce((tally, e) => {
if (!tally[e.name]) tally[e.name] = 0;
tally[e.name] = e.quantity
return tally;
}, {});
Комментарии:
1. Я совершенно уверен, что хотел получить массив объектов, а не объект с уникальными ключами, но это близко
2. Это, по сути, функция Object.entries (), но вы также можете выполнить итерацию forEach, упомянутую в другом ответе.