skip to Main Content
  var arr = [
    {item : banana_3, price : 100}, 
    {item : banana_2, price : 200}, 
    {item : apple, price : 500}];
    
    
    var arr2 = [
    {item : banana, price : 300}, 
    {item : apple, price : 500}];

I tried


    for(let i = 0; i<arr.length; i++){
  if(arr[i].item.includes('banana')){
     arr[i].price = arr[i+1].price ///???
    
   }
 }

I’d like to make arr2 from arr1, remove banana2 and banana3 elements within the array, and add up the price. How can I do that?

4

Answers


  1. You can use Array.prototype.reduce to group items based on a common prefix before the underscore:

    const arr = [
      {item: 'banana_3', price: 100}, 
      {item: 'banana_2', price: 200}, 
      {item: 'apple', price: 500}
    ];
    
    const arr2 = Object.values(arr.reduce((acc, curr) => {
      // Split the item name at the underscore to get the base name.
      const baseName = curr.item.split('_')[0];
      if (acc[baseName]) {
        // Add the price to the existing item.
        acc[baseName].price += curr.price;
      } else {
        // If no item yet, add a new one with the base name.
        acc[baseName] = {item: baseName, price: curr.price};
      }
      return acc;
    }, {}));
    
    console.log(arr2);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. You can use a simple regex to extract the first part of the item name (which I call the ‘key’), which would not include the underscore or anything after it. Then, you can use reduce to build up an object for each of those keys, incrementing the price of the matching object each time. Finally, use Object.values to return just the array of objects.

    const arr = [
      {item : 'banana_3', price : 100},
      {item : 'banana_2', price : 200},
      {item : 'apple', price : 500}
    ]
    
    const arr2 = Object.values(arr.reduce((a, {item, price}) => {
      let key = /([^_]+)/.exec(item)[1];
      (a[key] ??= {item: key, price: 0}).price += price
      return a
    }, {}))
    
    console.log(arr2)
    Login or Signup to reply.
  3. You could get all items and reduce with an object.

    const
        data0 = [{ item: 'banana_3', price: 100 }, { item: 'banana_2', price: 200 }, { item: 'apple', price: 500 }],
        data1 = [{ item: 'banana', price: 300 }, { item: 'apple', price: 500 }],
        result = Object.values([...data0, ...data1].reduce((r, { item, price }) => {
            [item] = item.split('_');
            r[item] ??= { item, price: 0 };
            r[item].price += price;
            return r;
        }, {}));
    
    console.log(result);
    Login or Signup to reply.
  4. You can avoid an intermediate array with mapping items with new names in a separate object and collect new items in an array:

    const reduce = (map, name) => (acc, {item, price}) => 
      ([name] = item.split('_'), (map[name] ??= acc[acc.length] = {item: name, price: 0}).price += price, acc);
    
    
    console.log(arr.reduce(reduce({}), []));
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script>
    const arr = [
      {item: 'banana_3', price: 100}, 
      {item: 'banana_2', price: 200}, 
      {item: 'apple', price: 500}
    ];
    </script>
    ` Chrome/120
    -------------------------------------------------------
    Alexander   1.00x  |  x1000000   94  101  102  111  144
    Sash        1.26x  |  x1000000  118  122  122  125  171
    -------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    const arr = [
      {item: 'banana_3', price: 100}, 
      {item: 'banana_2', price: 200}, 
      {item: 'apple', price: 500}
    ];
    
    // @benchmark Sash
    
    Object.values(arr.reduce((acc, curr) => {
      // Split the item name at the underscore to get the base name.
      const baseName = curr.item.split('_')[0];
      if (acc[baseName]) {
        // Add the price to the existing item.
        acc[baseName].price += curr.price;
      } else {
        // If no item yet, add a new one with the base name.
        acc[baseName] = {item: baseName, price: curr.price};
      }
      return acc;
    }, {}));
    
    // @benchmark Alexander
    
    const reduce = (map, name) => (acc, {item, price}) => 
      ([name] = item.split('_'), (map[name] ??= acc[acc.length] = {item: name, price: 0}).price += price, acc);
    
    arr.reduce(reduce({}), []);
    
    /*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search