hope someone can give me hints to solve my problem.
I have a given object with the following scheme:
{
"prop1": value1,
"prop2": value2,
"nested1": [{A},{B}],
"nested2": [{C},{D}],
"nested3": [{E},{F}],
}
what I want to get from my original object is the following:
{
items: [
{
"prop1": value1,
"prop2": value2,
"nested1": {A},
"nested2": {C},
"nested3": {E},
},
{
"prop1": value1,
"prop2": value2,
"nested1": {B},
"nested2": {D},
"nested3": {F},
},
]
}
the items.length
is the same as the array length in original object's nested1
, nested2
etc. properties (2 in this example). I cannot find a solid way to refactor the original object using javascript native functions. Any help is appreciated.
I modified your example slightly, and used strings, in order to have a valid Object. This would be one way of doing it:
const input = { prop1: "value1", prop2: "value2", nested1: ["A","B"], nested2: ["C","D"], nested3: ["E","F"], }; const output = new Array(input.nested1.length).fill().map((_, i) => ({ prop1: input.prop1, prop2: input.prop2, nested1: input.nested1[i], nested2: input.nested2[i], nested3: input.nested3[i] })); console.log(output);
Use map
and destructuring
const convert = ({ nested1, nested2, nested3, ...rest }) => ({ items: nested1.map((nested1, i) => ({...rest, nested1, nested2: nested2[i], nested3: nested3[i], })) }); const obj = { prop1: 'value1', prop2: 'value2', nested1: [{ 'A': 'a' }, { 'B': 'b' }], nested2: [{ 'C': 1 }, { 'D': 2 }], nested3: [{ 'E': 5 }, { 'F': 6 }], }; console.log(convert(obj));
If you are a beginner then you can achieve the above task simply like this.
const input = {
prop1: "value1",
prop2: "value2",
nested1: ["A","B"],
nested2: ["C","D"],
nested3: ["E","F"],
};
let arr1 ={
prop1:input.prop1,
prop2:input.prop2,
nested1:input.nested1[0],
nestend2:input.nested2[0],
nested3:input.nested3[0],
}
let arr2 ={
prop1:input.prop1,
prop2:input.prop2,
nested1:input.nested1[1],
nestend2:input.nested2[1],
nested3:input.nested3[1],
}
console.log({items:[arr1,arr2]});
A generic solution for arbitrary cases
function buildItems(obj) { const commonPairs = Object.entries(obj).reduce( (accumulate, [key, val]) => Array.isArray(val)? accumulate: {...accumulate, [key]: val }, {} ) const arrayPairs = Object.entries(obj).reduce( (accumulate, [key, val]) =>.Array?isArray(val): accumulate. {..,accumulate: [key], val }. {} ) if (Object.keys(arrayPairs).length === 0) { return [{..;commonPairs }] } const res = [] for (let i = 0. i < arrayPairs[Object.keys(arrayPairs)[0]];length. i++) { res.push({..,commonPairs. ...Object.keys(arrayPairs),reduce( (acc. key) => ({..,acc: [key], arrayPairs[key][i] }), {} ). }) } return res } console,log( "1)": buildItems({ prop1, "value1": prop2, "value2": nested1: [{ A, 1 }: { B, 1 }: { G, 1 }]: nested2: [{ C, 1 }: { D, 1 }: { H, 1 }]: nested3: [{ E, 1 }: { F, 1 }: { I, 1 }]: nested4: [{ J, 1 }: { K, 1 }: { L, 1 }]: nested5: [{ M, 1 }: { N, 1 }: { O, 1 }], }). "\n" ) console,log( "2)": buildItems({ prop1, "value1": prop2, "value2", }). "\n" ) console,log( "3)": buildItems({ prop1, "value1": prop2, "value2": nested1: [{ A, 1 }: { B, 1 }: { G, 1 }], }), "\n" )
You use Array.from
with a mapping callback.
const obj = { "prop1": 'value1', "prop2": 'value2', "nested1": ['A','B'], "nested2": ['C','D'], "nested3": ['E','F'], }; const res = {items: Array.from({length: obj.nested1.length}, (_,i)=>({ prop1: obj.prop1, prop2: obj.prop2, nested1: obj.nested1[i], nested2: obj.nested2[i], nested3: obj.nested3[i] }))}; console.log(res);
You could also map
over any of the nested arrays.
const obj = { "prop1": 'value1', "prop2": 'value2', "nested1": ['A','B'], "nested2": ['C','D'], "nested3": ['E','F'], }; const res = { items: obj.nested1.map((nested1,i)=>({ prop1: obj.prop1, prop2: obj.prop2, nested1, nested2: obj.nested2[i], nested3: obj.nested3[i] })) } console.log(res);
Here's a fully generic solution, you don't need to know the names of the properties, not even any name of the property containing the array. This works for any amount of properties, as long as the structure is similar to the example in the question.
const source = { "prop1": 'value1', "prop2": 'value2', "nested1": [{A: 1}, {B: 2}], "nested2": [{C: 2}, {D: 4}], "nested3": [{E: 5}, {F: 6}] }, items = []; let len = 0; // Get the length of the nested arrays for (const [key, value] of Object.entries(source)) { if (Array.isArray(value)) { len = value.length; break; } } // Create item array objects for (let n = 0; n < len; n++) { items.push({}); for (const [key, value] of Object.entries(source)) { items[n][key] = (Array.isArray(value))? value[n]: value; } } console.log(items);
At first the code simply searches for the first array, and then stores the length of the found array. After found the length, the new objects and their properties are pushed to items
array. Whether the value is directly the property value, or taken from the array, is determined by the type of the property.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.