Efficient way to convert Object arrays into collection in Javascript

守給你的承諾、 提交于 2021-02-10 03:21:52

问题


const myObj = {
 a: [1, 2, 3],
 b: [2, 4, 6],
 c: [10, 20, 30]
}

Into

const myCollection = [
  {a: 1, b: 2, c: 10},
  {a: 2, b: 4, c: 20},
  {a: 3, b: 6, c: 30}
]

I tried combinations of Object.entries, Object.keys and map but I'm always finding myself iterating twice or more over myObj and I'm not happy with any solution I came up with. So what is the most efficient (in terms of time complexity) and elegant way that you can think to achieve that?


回答1:


You could reduce the entries and map nested arrays.

const
    object = { a: [1, 2, 3], b: [2, 4, 6], c: [10, 20, 30] },
    result = Object
        .entries(object)
        .reduce((r, [k, a]) => a.map((v, i) => ({ ...r[i], [k]: v })), []);

console.log(result);



回答2:


Just in case you'd need variable length:

const myObj = {
  a: [1, 2, 3],
  b: [2, 4, 6,8, 10],
  c: [10, 20, 30, 40],
};

let myCollection = [];

Object.keys(myObj).forEach((k) => {
  for (let i = 0; i < myObj[k].length; i++) {
    if (!myCollection[i]) myCollection.push({});
    myCollection[i][k] = myObj[k][i];
  }
});
console.log(myCollection);



回答3:


That can be done using Array.reduce. I have attached the conversion code.

const myObj = {
 a: [1, 2, 3],
 b: [2, 4, 6],
 c: [10, 20, 30]
}

const myCollection = [
  {a: 1, b: 2, c: 10},
  {a: 2, b: 4, c: 20},
  {a: 3, b: 6, c: 30}
]

const maxLength = Math.max(...Object.values(myObj).map(item => item.length));

const myObjKeys = Object.keys(myObj);
const result = [ ...Array(maxLength).keys() ].map((index) => {
  return myObjKeys.reduce((acc, curKey) => {
    if (myObj[curKey].length > index) {
      acc[curKey] = myObj[curKey][index];
    }
    return acc;
  }, {});
});
console.log(result);



回答4:


Using ramdajs, I could suggest you a short way like below

const myObj = {
  a: [1, 2, 3],
  b: [2, 4, 6],
  c: [10, 20, 30]
}

const res = R.map(
  R.zipObj(R.keys(myObj)),
  R.values(myObj)
)

console.log(res)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

In ramdajs homepage, criteria 3 in What's Different, it cited that

The parameters to Ramda functions are arranged to make it convenient for currying. The data to be operated on is generally supplied last.




回答5:


You can use map() on Object.values and then use reduce() on each value.

const myObj = {
 a: [1, 2, 3],
 b: [2, 4, 6],
 c: [10, 20, 30]
}

let keys = Object.keys(myObj);
const arr = Object.values(myObj).map((a) => a.reduce((ac, a, i) => ({...ac, [keys[i]]:a}), {}));
console.log(arr)


来源:https://stackoverflow.com/questions/64135972/efficient-way-to-convert-object-arrays-into-collection-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!