1

I have a sample array bunch as

let bunch = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}]

I am trying to split the object to its quantity times --> if fruit is banana and quantity > 1 as:

//newBunch --> [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 1},{fruit: "banana" , quantity: 1},{fruit: "banana" , quantity: 1}]

I have tried using reduce as :

let bunch = [{fruit: "apple" , quantity: 1},{fruit: "banana" , quantity: 3}]
let res = bunch.reduce((acc,curr)=>{
        if(curr.quantity > 1 && 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)

I get the expected o/p using above snippet , but there would be an efficient way to do this (less code probably ) or would you just suggest to go with the current solution? please guide me along this. TIA

4 Answers 4

2

You could use .forEach() method to iterate over the array and then create new objects depending on the value of quantity property. You can push these newly created objects in another array that will hold all the objects.

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);

Sign up to request clarification or add additional context in comments.

3 Comments

and adding a if to check fruit === 'banana'
I don't understand what you mean. Could you elaborate what you are trying to say?
actually I am trying to do this for fruit banana , but the solution will split for all fruits of quantity > 1 , I understood but for others ref ..
2

You can use flatMap and 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})
})

5 Comments

Don't use .fill() method to insert an object in the array because in case of banana, there will be a single object that will be inserted at three indexes of the array. For details, see: MDN -Array.prototype.fill()
@Yousaf how does that affect , could you please explain
The object with banana will be inserted at three indexes, i.e. 1, 2, and 3 but the underlying object will be only one. So if you change the object at second index, these changes will be reflected in the objects at index 2 and 3 as well because in the memory there is only one object. You can test the problem by changing the quantity of the object at second index and then inspect the objects at index 2 and 3
@Yousaf, good point, depends on how someone is planning to use the resulting array. If the repeated elements need to be changed, then this approach may not work, because the repeated elements are a reference to a single object.
@Yousaf makes sense , thanks again :) .... in my case the objects are static and may be I can use this approach then
1

You may use Array.prototype.reduce() to traverse your source array.

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%;}

3 Comments

reduce again ahh :) ... thanks @Yevgen ... One Q , _ is that buffer which holds result ?
yes , thanks for the compatibilty note .... But I feel little harder to understand this answer , would be great with little more explanation :)
absolutely performance is more imp .... thanks for explanation too :) ... the chosen answer consequences considered later and changed to other and it is much more readable and simple ...
1

I suggest using Array.prototype.flatMap() and 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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.