问题
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