skip to Main Content

I have data that looks as follows:

[
   {
      "Type1":[
         {
            "ID":2,
            "DATE":"2017-08-08",
            "SENDER":3,
         },
         {
            "ID":1,
            "DATE":"2017-07-07",
            "SENDER":2,
         },
         {
            "ID":1,
            "DATE":"2017-06-07",
            "SENDER":3,
         }
      ]
   }
]

I am trying to get it so each ID has its own node so that I can loop through each ID and then loop through its associated dates/sender data in Vue. However, I am struggling with map of how to do this. The data is too flat for looping through as I need to loop through ID then its associated items. So far this is what I have using reduce but this still does not create the expected result and is object rather than an array of objects like my original result:

                        this.TimelineV2 = this.timelineArr['Type1'].reduce(function (r, a) {
                            r[a.ID] = r[a.ID] || [];
                            r[a.ID].push(a);
                            return r;

I have found examples of making arrays flat but the opposite is difficult to find examples as there is so many shapes of arrays to get a good example of what I want:

[
   {
      "Type1":[
         {
            "ID":2,
            "DETAILS":[{
                "DATE":"2017-08-08",
                "SENDER":3,
            }]
         },
         {
            "ID":1,
            "DETAILS":[{
                "DATE":"2017-07-07",
                "SENDER":2,
            },
            {
                "DATE":"2017-06-07",
                "SENDER":3,
            },
            ]
         }
      ]
    }
]

2

Answers


  1. You first need to map() every element in the input to an output object of the structure { Type1: <some value here>}. Then to get the value to put there first group by ID using reduce() (and the nullish coalescing assignment operator ??=) and then use Object.entries() together with map() to create the desired structure of the output.

    const input = [{
      "Type1": [{
          "ID": 2,
          "DATE": "2017-08-08",
          "SENDER": 3,
        },
        {
          "ID": 1,
          "DATE": "2017-07-07",
          "SENDER": 2,
        },
        {
          "ID": 1,
          "DATE": "2017-06-07",
          "SENDER": 3,
        }
      ]
    }];
    
    
    const test = input.map(x => {
      const groupedById = x.Type1.reduce((acc, cur) => ((acc[cur.ID] ??= []).push({
        DATE: cur.DATE,
        SENDER: cur.SENDER
      }), acc), {});
      return {
        Type1: Object.entries(groupedById).map(([id, details]) => ({
          ID: id,
          DETAILS: details
        }))
      };
    });
    
    
    console.log(test);
    //const output = input.map(x => );
    .as-console-wrapper {
        max-height: 100% !important;
        top: 0;
    }

    Obviously the code could be written shorter, but for clarity I kept it like this.

    Login or Signup to reply.
  2. To transform your data into the desired format, you can use a combination of reduce() and map() methods to iterate over the original array and create a new array with the desired structure. Here’s an example implementation:

        const data = [
       {
          "Type1":[
             {
                "ID":2,
                "DATE":"2017-08-08",
                "SENDER":3,
             },
             {
                "ID":1,
                "DATE":"2017-07-07",
                "SENDER":2,
             },
             {
                "ID":1,
                "DATE":"2017-06-07",
                "SENDER":3,
             }
          ]
       }
    ];
    
    const transformedData = data.map(item => {
      const { Type1 } = item;
      const transformedType1 = Type1.reduce((acc, curr) => {
        const { ID, DATE, SENDER } = curr;
        const existing = acc.find(item => item.ID === ID);
        if (existing) {
          existing.DETAILS.push({ DATE, SENDER });
        } else {
          acc.push({ ID, DETAILS: [{ DATE, SENDER }] });
        }
        return acc;
      }, []);
      return { Type1: transformedType1 };
    });
    
    console.log(transformedData);
    

    This code will produce an output that matches your desired format:

    [   {      "Type1":[         {            "ID":2,            "DETAILS":[{                "DATE":"2017-08-08",                "SENDER":3,            }]
             },
             {
                "ID":1,
                "DETAILS":[{
                    "DATE":"2017-07-07",
                    "SENDER":2,
                },
                {
                    "DATE":"2017-06-07",
                    "SENDER":3,
                },
                ]
             }
          ]
        }
    ]
    

    The code works by first iterating over the original array using map(). For each item in the array, we extract the Type1 property and then use reduce() to iterate over its contents. For each item in Type1, we check if an item with the same ID already exists in the accumulator (acc). If it does, we push the DATE and SENDER values into its DETAILS array. Otherwise, we create a new object with the ID and a DETAILS array containing the current DATE and SENDER, and push it into the accumulator. Finally, we wrap the transformed Type1 array in a new object with a Type1 property and return it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search