skip to Main Content

I have a dynamic array of nested objects as below:

[
    {
        "fields": [
            {
                "field-1": {
                    "id": "field-1",
                    "value": "a1"
                },
                "field-2": {
                    "id": "field-2",
                    "value": "a2"
                },
                "field-3": {
                    "id": "field-3",
                    "value": "a3"
                }
            }
        ]
    },
    {
        "fields": [
            {
                "field-1": {
                    "id": "field-1",
                    "value": "b1"
                },
                "field-2": {
                    "id": "field-2",
                    "value": "b2"
                },
                "field-3": {
                    "id": "field-3",
                    "value": "b3"
                }
            }
        ]
    }
]

I want to parse/reduce this array to below kind of structure:

[
    {
        "field-1": "a1",
        "field-2": "a2",
        "field-3": "a3"
    },
    {
        "field-1": "b1",
        "field-2": "b2",
        "field-3": "b3"
    },
]

While I already have a verbose way of iterating over the array and constructing the new one, I wanted to know if it is possible to get the structure using the reduce method, as that would be faster?

4

Answers


  1. You can use reduce to do it

    const result = raw
      .map(row => Object.entries(row.fields[0])
        .reduce((acc, [key, { value }]) => {
           acc[key] = value
           return acc
        }, {})
      )
    
    console.log(result)
    <script>
      const raw = [{
          "fields": [{
            "field-1": {
              "id": "field-1",
              "value": "a1"
            },
            "field-2": {
              "id": "field-2",
              "value": "a2"
            },
            "field-3": {
              "id": "field-3",
              "value": "a3"
            }
          }]
        },
        {
          "fields": [{
            "field-1": {
              "id": "field-1",
              "value": "b1"
            },
            "field-2": {
              "id": "field-2",
              "value": "b2"
            },
            "field-3": {
              "id": "field-3",
              "value": "b3"
            }
          }]
        }
      ]
    </script>
    Login or Signup to reply.
  2. You Can try this code

    var convert=[];
    for (let i=0; i< test.length; i++){
        var obj={};
        Object.entries(test[i]).forEach(entry => { 
            const [key, value] = entry; 
            for(let j=0; j < value.length; j++){
                Object.entries(value[j]).forEach(s => { var [ k,v ] = s; obj[k]= v.value  }); 
            }
        })
        convert[i]=obj
    }
    console.log(convert);
    <script>
    var test=[
        {
            "fields": [
                {
                    "field-1": {
                        "id": "field-1",
                        "value": "a1"
                    },
                    "field-2": {
                        "id": "field-2",
                        "value": "a2"
                    },
                    "field-3": {
                        "id": "field-3",
                        "value": "a3"
                    }
                }
            ]
        },
        {
            "fields": [
                {
                    "field-1": {
                        "id": "field-1",
                        "value": "b1"
                    },
                    "field-2": {
                        "id": "field-2",
                        "value": "b2"
                    },
                    "field-3": {
                        "id": "field-3",
                        "value": "b3"
                    }
                }
            ]
        }
    ];</script>
    Login or Signup to reply.
  3. Here is my version:

    const res = data
      .flatMap((obj) => obj.fields)
      .map((obj) =>
        Object.entries(obj).reduce((p, [k, v]) => ({ ...p,
          [k]: v.value
        }), {})
      );
    
    console.log(JSON.stringify(res, null, 4));
    <script>
      const data = [{
          "fields": [{
            "field-1": {
              "id": "field-1",
              "value": "a1"
            },
            "field-2": {
              "id": "field-2",
              "value": "a2"
            },
            "field-3": {
              "id": "field-3",
              "value": "a3"
            }
          }]
        },
        {
          "fields": [{
            "field-1": {
              "id": "field-1",
              "value": "b1"
            },
            "field-2": {
              "id": "field-2",
              "value": "b2"
            },
            "field-3": {
              "id": "field-3",
              "value": "b3"
            }
          }]
        }
      ]
    </script>

    Explanation

    We first flatMap() the given array since we have array inside array, to get the following:

    const x = data.flatMap((obj) => obj.fields);
    

    Output:

    [
        {
            "field-1": {
                "id": "field-1",
                "value": "a1"
            },
            "field-2": {
                "id": "field-2",
                "value": "a2"
            },
            "field-3": {
                "id": "field-3",
                "value": "a3"
            }
        },
        {
            "field-1": {
                "id": "field-1",
                "value": "b1"
            },
            "field-2": {
                "id": "field-2",
                "value": "b2"
            },
            "field-3": {
                "id": "field-3",
                "value": "b3"
            }
        }
    ]
    

    Now for each object in the above array, I just need to change the value of each key in each object. So we need to call map on the previous output and for each object, generate our desired object using reduce():

    const res = x.map((obj) => Object.entries(obj).reduce((p, [k, v]) => ({ ...p, [k]: v.value }), {}))
    

    Output:

    [
        {
            "field-1": "a1",
            "field-2": "a2",
            "field-3": "a3"
        },
        {
            "field-1": "b1",
            "field-2": "b2",
            "field-3": "b3"
        }
    ]
    
    Login or Signup to reply.
  4. The JSON.parse reviver and JSON.stringify replacer can be used to modify nested values :

    const data = [{"fields":[{"field-1":{"id":"field-1","value":"a1"},
                              "field-2":{"id":"field-2","value":"a2"},
                              "field-3":{"id":"field-3","value":"a3"}}]},
                  {"fields":[{"field-1":{"id":"field-1","value":"b1"},
                              "field-2":{"id":"field-2","value":"b2"},
                              "field-3":{"id":"field-3","value":"b3"}}]}]
    
    let result = JSON.parse(JSON.stringify(data), (k, v) => v.value ?? v.fields?.[0] ?? v)
    
    console.log( result )
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search