sharpshooter
sharpshooter

Reputation: 61

serialize array into object in JSON for API

I am working on Angular 12, in my TS file
I have an array response from a file upload like this-

[
  {
    "id": "7",
    "name": "xyz",
    "job": "doctor",
    "preference": "1"
  },
  {
    "id": "7",
    "name": "xyz",
    "job": "nurse",
    "preference": "2"
  },
  {
    "id": "7",
    "name": "xyz",
    "job": "manager",
    "preference": "3"
  },
  {
    "id": "7",
    "name": "xyz",
    "job": "assistant",
    "preference": "4"
  },
  {
    "id": "7",
    "name": "xyz",
    "job": "chairman",
    "preference": "5"
  },
  {
    "id": "7",
    "name": "xyz",
    "job": "designer",
    "preference": "6"
  }
]

I want to convert this array to an object in JSON like this-

[
  {
    "id": "7",
    "name": "xyz",
    "array1": [
      {
        "date": "today's Date,",
        "endDate": "somedate",
        "lastUpdatedBy": "someuser",
        "array2": [
          {
            "job": "doctor",
            "preference": "1"
          },
          {
            "job": "nurse",
            "preference": "2"
          },
          {
            "job": "manager",
            "preference": "3"
          },
          {
            "job": "assistant",
            "preference": "4"
          },
          {
            "job": "chairman",
            "preference": "5"
          },
          {
            "job": "designer",
            "preference": "6"
          }

        ]
      }
    ]
  }
]

So based on the id and name combination I want to create the object in JSON which will be passed to an API, I've been trying many things by using map or arrays inside array but having a hard time to succeed. Any help would be appreciated. In map it will not take duplicate keys for same id & name combination. I have tried to create a customized object and loop through it but each time I get a separate result. After looping through the array I am trying to build an object like this, but it doesn't produce expected result.

my code-

let object = {
        id: data[i].id,
        name: data[i].name,
        array1:[ 
          {
          date: dateParam,
          endDate: '',
          lastUpdatedBy: 'me',
          array2: [
            {
            job: data[i].job,
            preference: data[i].preference
          }
        ]
        }
      ]
      };

Upvotes: 1

Views: 634

Answers (1)

Martin Devillers
Martin Devillers

Reputation: 17992

I'd separate this in two steps:

  1. Group the items using id + name as the key
  2. Transform the grouped structure to the desired output

Click here for a working sandbox

Below is the code:


function groupBy<T, TKey>(list: T[], keyGetter: (arg: T) => TKey) {
  const map = new Map<TKey, T[]>();
  list.forEach((item) => {
    const key = keyGetter(item);
    const collection = map.get(key);
    if (!collection) {
      map.set(key, [item]);
    } else {
      collection.push(item);
    }
  });
  return map;
}

const groupedInput = groupBy(input, (x) => x.id + x.name);

const output = Array.from(groupedInput.entries()).map(([key, value]) => ({
  id: value[0].id,
  name: value[0].name,
  array1: value.map((x) => ({ job: x.job, preference: x.preference }))
}));

console.log(output);

Using input with the data you gave:

const input = [
  {
    id: "7",
    name: "xyz",
    job: "doctor",
    preference: "1"
  },
  {
    id: "7",
    name: "xyz",
    job: "nurse",
    preference: "2"
  },
  {
    id: "7",
    name: "xyz",
    job: "manager",
    preference: "3"
  },
  {
    id: "7",
    name: "xyz",
    job: "assistant",
    preference: "4"
  },
  {
    id: "7",
    name: "xyz",
    job: "chairman",
    preference: "5"
  },
  {
    id: "7",
    name: "xyz",
    job: "designer",
    preference: "6"
  }
];

This will output:


[{
        "id": "7",
        "name": "xyz",
        "array1": [{
                "job": "doctor",
                "preference": "1"
            }, {
                "job": "nurse",
                "preference": "2"
            }, {
                "job": "manager",
                "preference": "3"
            }, {
                "job": "assistant",
                "preference": "4"
            }, {
                "job": "chairman",
                "preference": "5"
            }, {
                "job": "designer",
                "preference": "6"
            }
        ]
    }
]

Upvotes: 2

Related Questions