#javascript #arrays
#javascript #массивы
Вопрос:
У меня есть образец массива bunch
в виде
let bunch = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}]
Я пытаюсь разделить объект на его количество раз -> если fruit
есть banana
и quantity
> 1
как:
//newBunch --> [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 1},{fruit: "banana" , quantity: 1},{fruit: "banana" , quantity: 1}]
Я попытался использовать reduce как :
let bunch = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}]
let res = bunch.reduce((acc,curr)=>{
if(curr.quantity > 1 amp;amp; curr.fruit==='banana'){
var arr = []
for(let i=0; i < curr.quantity ; i ){
var fr = {}
fr.fruit = 'banana';
fr.quantity = 1;
arr.push(fr)
}
acc.push(...arr)
}
else{
acc.push(curr)
}
return acc
},[])
console.log(res)
Я получаю ожидаемый ввод-вывод, используя приведенный выше фрагмент, но был бы эффективный способ сделать это (возможно, меньше кода), или вы бы просто предложили использовать текущее решение? пожалуйста, проведите меня по этому вопросу. TIA
Ответ №1:
Вы можете использовать .forEach()
метод для итерации по массиву, а затем создавать новые объекты в зависимости от значения quantity
свойства. Вы можете поместить эти вновь созданные объекты в другой массив, который будет содержать все объекты.
let bunch = [
{ fruit: 'apple', quantity: 1 },
{ fruit: 'banana', quantity: 3 },
];
const result = [];
bunch.forEach(obj => {
for (let i = 1; i <= obj.quantity; i ) {
result.push({ ...obj, quantity: 1 });
}
});
console.log(result);
Комментарии:
1. и добавление a
if
для проверкиfruit === 'banana'
2. Я не понимаю, что вы имеете в виду. Не могли бы вы уточнить, что вы пытаетесь сказать?
3. на самом деле я пытаюсь сделать это для фруктов
banana
, но решение будет разделено на все фрукты с количеством> 1, я понял, но для других ссылка..
Ответ №2:
Вы можете использовать flatMap и Array.prototype.fill
let bunch = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}]
let result = bunch.flatMap((fruit) => {
return Array(fruit.quantity).fill({ ...fruit, quantity: 1})
})
Комментарии:
1. Не используйте
.fill()
метод для вставки объекта в массив, потому что в случаеbanana
, будет один объект, который будет вставлен по трем индексам массива. Подробнее см.: MDN -Array.prototype.fill()2. @Yousaf как это влияет, не могли бы вы объяснить
3. Объект с
banana
будет вставлен с тремя индексами, то есть 1, 2 и 3, но базовый объект будет только один. Поэтому, если вы измените объект со вторым индексом, эти изменения будут отражены и в объектах с индексами 2 и 3, потому что в памяти есть только один объект. Вы можете проверить проблему, изменив количество объекта по второму индексу, а затем проверить объекты по индексам 2 и 34. @Yousaf, хороший момент, зависит от того, как кто-то планирует использовать результирующий массив. Если повторяющиеся элементы необходимо изменить, этот подход может не сработать, поскольку повторяющиеся элементы являются ссылкой на один объект.
5. @Yousaf имеет смысл, еще раз спасибо 🙂 …. в моем случае объекты статичны, и, возможно, тогда я смогу использовать этот подход
Ответ №3:
Вы можете использовать Array.prototype.reduce()
для обхода вашего исходного массива.
- На каждой итерации вы просто подготавливаете разреженный массив определенного размера
quantity
, используяArray()
конструктор - Используйте
Array.prototype.fill()
Array.prototype.map()
комбинацию и для заполнения вышеуказанного массива объектами, имеющими свойствоfruit
, равное исходному объекту и свойствуquantity
, заданному1
(этот подход более чистый, чем использование просто.fill()
для элементов непримитивного типа данных, таких как объекты) - Используйте
Array.prototype.push()
синтаксис вместе с расширением, чтобы поместить все элементы результирующего массива в.reduce()
накопитель
const src = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}],
result = src.reduce((acc, {fruit, quantity}) => {
acc.push(
...Array(quantity)
.fill()
.map(_ => ({
fruit,
quantity: 1
}))
)
return acc
}, [])
console.log(result)
.as-console-wrapper{min-height:100%;}
Комментарии:
1. уменьшите снова ах :)… спасибо @Yevgen … Один вопрос,
_
это тот буфер, который содержит результат?2. да, спасибо за примечание о совместимости …. Но мне немного сложнее понять этот ответ, было бы здорово с небольшим объяснением 🙂
3. абсолютно производительность выше …. спасибо и за объяснение :)… выбранный ответ был рассмотрен позже и изменен на другой, и он намного более удобочитаемый и простой…
Ответ №4:
Я предлагаю использовать Array.prototype.flatMap()
и Array.from()
let bunch = [
{ fruit: 'apple', quantity: 2 },
{ fruit: 'banana' , quantity: 3 },
{ fruit: 'starfruit', quantity: 1 },
];
const splitBunches = bunch.flatMap((fruit) => (
Array.from({ length: fruit.quantity }, () => ({ ...fruit, quantity: 1 }))
))
console.log(splitBunches)