简体   繁体   中英

Javascript manipulating with objects

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM