Reputation: 55
I have an object that looks like this:
obj={"a": [1,2],"b": [3,4],"c": [5,6]}
I need to create an array of objects where every object consists of each key with only one value corresponding to its order like this:
obj2=[{"a": 1, "b": 3, "c": 5},{"a": 2, "b": 4, "c": 6}]
Also, if I have a JSON string using JSON.stringify(obj)
, would it be somehow possible to create string corresponding to JSON.stringify(obj2)
directly from the first one?
Upvotes: 1
Views: 6394
Reputation: 20155
const obj = { "a": [1, 2], "b": [3, 4], "c": [5, 6] }
// create an array to store result
const result = []
// for each key in obj
Object.keys(obj).forEach(key => {
// for each array element of the property obj[key]
obj[key].forEach((value, index) => {
// if an object doesn't exists at the current index in result
// create it
if (!result[index]) {
result[index] = {}
}
// at the result index, set the key to the current value
result[index][key] = value
})
})
console.log(result)
Here is my algorithm, given the expected result .
Also, let's say i have a JSON string using JSON.stringify(obj), would it be somehow possible to create string corresponding to JSON.stringify(obj2) directly from the first one?
Yes, you could add .toJSON to obj:
const obj = { "a": [1, 2], "b": [3, 4], "c": [5, 6] }
Object.setPrototypeOf(obj, {
toJSON: function () {
const result = []
Object.keys(this).forEach(key => {
this[key].forEach((value, index) => {
if (!result[index]) {
result[index] = {}
}
result[index][key] = value
})
})
return JSON.stringify(result);
}
})
console.log(JSON.stringify(obj))
You can use Object.setPrototypeOf so that toJSON method is not counted as an enumerable key when Object.keys(obj).forEach iterates
Upvotes: 1
Reputation: 1712
You can iterate over the keys of the input object and construct the desired output with Array.prototype.reduce
var obj={"a": [1,2],"b": [3,4],"c": [5,6]};
var result = Object.keys(obj).reduce((a, k) => (obj[k].forEach((n, i) => a[i] = {...(a[i] || {}), ...{[k]: n}}), a),[]);
console.log(result);
Upvotes: 0
Reputation: 386600
You could use a single loop for the keys and another for the value and map a new array.
This works for same length arrays.
var object = { a: [1, 2], b: [3, 4], c: [5, 6] },
array = Object
.entries(object)
.reduce((r, [k, a]) => a.map((v, i) => Object.assign(r[i] || {}, { [k]: v })), []);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 26844
You can use Object.keys
and Object.values
to extract the keys and the values. Use Math.max
to get the max length of the values. Use for
to loop thru and use reduce
to make new object.
var obj = {"a": [1, 2],"b": [3, 4],"c": [5, 6]};
var keys = Object.keys(obj);
var values = Object.values(obj);
var obj2 = [];
for (i = 0; i < Math.max(...values.map(o => o.length)); i++) {
obj2.push(keys.reduce((c, v, k) => Object.assign(c, {[v]: values[k][i] || ""}), {}))
}
console.log(obj2);
This will work even if the given object values are not the same on length.
var obj = {
"a": [1, 2],
"b": [3, 4],
"c": [5, 6, 10]
};
var keys = Object.keys(obj);
var values = Object.values(obj);
var obj2 = [];
for (i = 0; i < Math.max(...values.map(o => o.length)); i++) {
obj2.push(keys.reduce((c, v, k) => Object.assign(c, {[v]: values[k][i] || ""}), {}))
}
console.log(obj2);
Upvotes: 1
Reputation: 1802
If your values (arrays) have the same length.
obj = {"a": [1,2],"b": [3,4],"c": [5,6]};
obj2 = [];
var keys = Object.keys(obj)
for (i = 0; i < obj[keys[0]].length; i++) {
temp = {};
keys.forEach(x => temp[x] = obj[x][i]);
obj2.push(temp);
}
console.log(obj2);
Upvotes: 0
Reputation: 6467
I believe this should do the trick:
obj={"a": [1,2],"b": [3,4],"c": [5,6]}
const transform = input => Object.values(input)[0]
.map((_, i) => Object.keys(input)
.reduce((prev, curr) => {
prev[curr] = input[curr][i]
return prev
}, {}))
const result = transform(obj)
console.dir(result)
This will only work on objects where each value is an array of the same length. You take each index of the first value, then create an object for each key, getting the value using the aforementioned index.
Upvotes: 0