skip to Main Content

heres a working example of what I’m trying to do:

  private mergeData(dataArray) {
    const mergedData = {
      items: [],
      money: {
        money1: 0,
        money2: 0,
        money3: 0,
      }
    }
    for (const data of dataArray) {
      mergedData.money.money1 += data.money.money1
      mergedData.money.money2 += data.money.money2
      mergedData.money.money3 += data.money.money3
      mergedData.items = [...mergedData.items, ...data.items]
    }

    return mergedData
  }

I’m looking to optimize this as something about it feels smelly.

I have Lodash available in my project and would ideally use it if possible.

I would like to add more details as I seem to have posted this too hastily

dataArray looks like an array of these objects

{
      items: [],
      money: {
        money1: 0,
        money2: 0,
        money3: 0,
      }
    }

And items is just an object with string key:value pairs

I’m looking to make this more concise and possibly optimize performance on item merging

Thanks.

3

Answers


  1. You can use reduce

    private mergeData(dataArray) {
      const mergedData = {
        items: [],
        money: {
          money1: 0,
          money2: 0,
          money3: 0,
        }
      }
    
      return dataArray.reduce((acc, curr) => {
        acc.items.push(...curr.items)
        acc.money.money1 += curr.money.money1
        acc.money.money2 += curr.money.money2
        acc.money.money3 += curr.money.money3
        return acc;
    
      }, mergedData)
    
    }
    
    Login or Signup to reply.
  2. You can optimize the merging of the array of objects using lodash’s _.mergeWith() function to merge the "money" properties and _.concat() to merge the "items" arrays. Here’s an example of how you can do it:

    const _ = require('lodash');
    
    function mergeData(dataArray) {
      const mergedData = {
        items: [],
        money: {
          money1: 0,
          money2: 0,
          money3: 0,
        },
      };
    
      for (const data of dataArray) {
        // Merge "money" properties
        _.mergeWith(mergedData.money, data.money, (objValue, srcValue) => objValue + srcValue);
    
        // Concatenate "items" arrays
        mergedData.items = _.concat(mergedData.items, data.items);
      }
    
      return mergedData;
    }
    
    // Example dataArray
    const dataArray = [
      {
        items: [{ key1: 'value1' }],
        money: {
          money1: 10,
          money2: 20,
          money3: 30,
        },
      },
      {
        items: [{ key2: 'value2' }],
        money: {
          money1: 5,
          money2: 15,
          money3: 25,
        },
      },
    ];
    
    const mergedData = mergeData(dataArray);
    console.log(mergedData);
    Login or Signup to reply.
  3. I would simplify the code using the following 2 points.

    1. Reuse the items array instead of creating a new one each iteration. This can be done by pushing data.items into the existing array.

      items.push(...data.items);
      
    2. Collect the money keys in a separate array before you start looping dataArray.

        const moneyKeys = Object.keys(money)
      

      Then add the values of the listed keys to the total for each data.money in dataArray.

      moneyKeys.forEach(key => money[key] += data.money[key])
      
    function mergeData(dataArray) {
      const items = [];
      const money = { money1: 0, money2: 0, money3: 0 };
      const moneyKeys = Object.keys(money);
      
      for (const data of dataArray) {
        items.push(...data.items);
        moneyKeys.forEach(key => money[key] += data.money[key]);
      }
      
      return { items, money };
    }
    
    console.log(mergeData([
      {
        items: ['a', 'b', 'c'],
        money: { money1: 2, money2: 4, money3: 8 },
      }, {
        items: ['x', 'y', 'z'],
        money: { money1: 1, money2: 2, money3: 3 },
      }
    ]));

    You can replace the for...of loop with something faster if you really need the additional speed.

    ps. If possible I would personally replace { money1: 0, money2: 0, money3: 0 } with a simple array [0, 0, 0]. As soon as you start numbering your attributes you probably want to use an array instead. This only works if you have control over the build process of the input structure.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search