Search code examples
javascriptecmascript-6lodash

JS transform deeply nested array of objects at the top level with renaming


I would like to simplify this nested array of objects move some items at the top level with a new property name. Given this data:

let data = [
      {
        "id": 1001,
        "model": "Lemon",
        "length": "4",
        "details": [
          {
            "id": 38,
            "kind": "D",
            "color": "Gray",
            "specifics": {
              "id": 3
            }
          }
        ]
      },
      {
        "id": 1002,
        "model": "Botanica",
        "length": "2",
        "details": [
          {
            "id": 39,
            "kind": "A",
            "color": "Yellow",
            "specifics": {
              "id": 1
            }
          },
          {
            "id": 40,
            "kind": "B",
            "color": "Green",
            "specifics": {
              "id": 2
            }
          },
        ]
      }
    ];

My desired output:

    [
      {
        "id": 3,
        "model": "Lemon",
        "color": "Gray",
      },
      {
        "id": 1,
        "model": "Botanica",
        "color": "Yellow",
      },
      {
        "id": 2,
        "model": "Botanica",
        "color": "Green",
      }
    ]

Or much better to combine the model and color:

[
  {
    "id": 3,
    "model": "Lemon - Gray"
  },
  {
    "id": 1,
    "model": "Botanica - Yellow"
  },
  {
    "id": 2,
    "model": "Botanica - Green"
  }
]

If there are multiple specifics, it would also create a new object together with the model and color, then it would move at the top. Here's what I've tried so far:

const result = data.map(({ details, ...d }) => ({
  ...d,
  data: details.map(({ specifics, ...s }) => ({
    ...r,
    id: specifics.id
  }))
}));

But it seems that I can't get the right result. How to simplify this one? Thanks.


Solution

  • First, we need to loop through the data array. We can get the model from the data element namely item. Then we need to loop through that item.details array. From that we can get id, detail.color. Hers's the full code.

    let data = [
          {
            "id": 1001,
            "model": "Lemon",
            "length": "4",
            "details": [
              {
                "id": 38,
                "kind": "D",
                "color": "Gray",
                "specifics": {
                  "id": 3
                }
              }
            ]
          },
          {
            "id": 1002,
            "model": "Botanica",
            "length": "2",
            "details": [
              {
                "id": 39,
                "kind": "A",
                "color": "Yellow",
                "specifics": {
                  "id": 1
                }
              },
              {
                "id": 40,
                "kind": "B",
                "color": "Green",
                "specifics": {
                  "id": 2
                }
              },
            ]
          }
        ];
    
    const result = data.reduce((result, item) => {
      return [...result, ...item.details.map((detail) => {
        return {
          id: detail.specifics.id,
          model: item.model + " - " + detail.color
        }
      } )]
    }, []);
    
    console.log(result);