Home > Software design >  JS/lodash - Can we efficiently change an 'array of Object' having value 'Array of Obj
JS/lodash - Can we efficiently change an 'array of Object' having value 'Array of Obj

Time:10-29

I have used lodash to create chunks of arrays (batches).

let values = {
    'key1' : [lotsOfValues1],
    'key2' : [lotsOfValues2]
};
let keys = ['key1', 'key2'];
let arrObj = [];
keys.forEach((key) => {
    arrObj.push([key] : lodash.chunk(values[key], 20)) // it will break lotsOfValues arrays into chunks of size 20
});
/* Now arrObj = [
  {
    key1: [[someVals1], [someVals2], [someVals3]],
  },
  {
    key2: [[someVals4], [someVals5]],
  },
];
*/

Is there a way we can efficiently change an array of Objects -

const arrObj = [
      {
        key1: [[someVals1], [someVals2], [someVals3]],
      },
      {
        key2: [[someVals4], [someVals5]],
      },
    ];

into an array of Objects with instead of array of object as value just individual array elements. Something like this -

const arrObjTransformed = [
      { key1: [someVals1] },
      { key1: [someVals2] },
      { key1: [someVals3] },
      { key2: [someVals4] },
      { key2: [someVals5] },
    ];

any help would be highly appreciated.

I tried looping through arrObj and for each element I had another loop which will form a new object with each value and keep updating the final output array.

But I somehow feel there can be a cleaner way to achieve it.

CodePudding user response:

You can use _.flatMap() to iterate the array of objects, and then to iterate the object's properties, and map the array of chunk into new objects that contain the array, and a specific chunk:

const { flatMap, map } = _

const arr = [{
    'key1': [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
  },
  {
    'key2': [[4, 4, 4], [5, 5, 5], [6, 6, 6]],
  },
  {
    'key3': [[7, 7, 7]]
  }
]

const result = flatMap(arr, obj => 
  flatMap(obj, 
    (v, k) => map(v, chunk => ({
      [k]: chunk
    }))
  )
)
console.log(result)
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

However, you can just take the original object, create the chunks, and the requested structure in a single step:

const { flatMap, map, chunk } = _

const obj = {
  'key1': [1, 1, 1, 2, 2, 2, 3, 3, 3],
  'key2': [4, 4, 4, 5, 5, 5, 6, 6, 6],
  'key3': [7, 7, 7]
}

const result = flatMap(obj, (arr, key) => 
  map(chunk(arr, 3), chunk => ({
    [key]: chunk
  }))
)
  
console.log(result)
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

CodePudding user response:

Let's try, it's a loop over the arr of object, then for each of its keys "multiply" by the arrays of that key. Something like this.

const arrObj = [{
    'key1': [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
  },
  {
    'key2': [[4, 4, 4], [5, 5, 5], [6, 6, 6]],
    'key3': [[7, 7, 7]]
  }
]

var result = []
arrObj.forEach(function(obj) {
  Object.keys(obj).forEach(function(key) {
    var arr_of_arr = obj[key];
    arr_of_arr.forEach(function(arr) {
      var newman = {}
      newman[key] = arr;
      result.push(newman)

    })
  })
})

console.log(result)
.as-console-wrapper {
  max-height: 100% !important
}

  • Related