Search code examples
javascriptjavascript-objects

Create an array of objects based on an object if one or more properties have multiple values differentiated by a comma


i'm trying to duplicate objects based on two properties that have multiple values differentiated by a comma. For example:

I have an object

const obj = {
  id: 1
  date: "2021"
  tst1: "111, 222"
  tst2: "AAA, BBB"
}

And I would like the result to be an array of 2 objects in this case (because there are 2 values in tst1 OR tst2, these 2 properties will always have the same nr of values differentiated by a comma)

[{
  id: 1,
  date: "2021",
  tst1: "111",
  tst2: "AAA",
},
{
  id: 1,
  date: "2021",
  tst1: "222",
  tst2: "BBB",
}]

What I tried is this:

I created a temporary object

const tempObject = {
      id: obj.id,
      date: obj.date,
}

And then I would split and map the property that has multiple values, like this:

cont newObj = obj.tst1.split(",").map(function(value) {
    let finalObj = {}
    return finalObj = {
        id: tempObject.id,
        date: tempObject.date,
        tst1: value,
    })

And now, the newObj is an array of objects and each object contains a value of tst1. The problem is I still have to do the same for the tst2...

And I was wondering if there is a simpler method to do this...

Thank you!


Solution

  • Here is an example that accepts an array of duplicate keys to differentiate. It first maps them to arrays of entries by splitting on ',' and then trimming the entries, then zips them by index to create sub-arrays of each specified property, finally it returns a result of the original object spread against an Object.fromEntries of the zipped properties.

    const mapDuplicateProps = (obj, props) => {
      const splitProps = props.map((p) =>
        obj[p].split(',').map((s) => [p, s.trim()])
      );
      // [ [[ 'tst1', '111' ], [ 'tst1', '222' ]], [[ 'tst2', 'AAA' ], [ 'tst2', 'BBB' ]] ]
    
      const dupeEntries = splitProps[0].map((_, i) => splitProps.map((p) => p[i]));
      // [ [[ 'tst1', '111' ], [ 'tst2', 'AAA' ]], [[ 'tst1', '222' ], [ 'tst2', 'BBB' ]] ]
    
      return dupeEntries.map((d) => ({ ...obj, ...Object.fromEntries(d) }));
    };
    
    const obj = {
      id: 1,
      date: '2021',
      tst1: '111, 222',
      tst2: 'AAA, BBB',
    };
    
    console.log(mapDuplicateProps(obj, ['tst1', 'tst2']));