Home > other >  How to create create a new custom(specific) object and map the data from Array of object
How to create create a new custom(specific) object and map the data from Array of object

Time:08-10

I get a response from backend which is an array of object which is as below mentioned

[{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"[email protected]"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}]

I am trying to get all the details of users from the backend which are stored in different tables like a separate table for Phone, Address, Email etc. And similarly for EmailShared or PhoneShared which contains the information regarding with which organisation has the information has been shared. As we can see that HSBC has the address of George.

But what I want to try and do is that have all the information in a single object instead of a different one for each attribute(address, phone, email). What right now we have is the below one

[
    {
      addressID: "1"
      address_value: "27 London Street E146AA"
      expDate: "2022-12-12T17:09:37.000Z"
      firstName: "George"
      lastName: "Russel"
      userID: 1
    },
    {
      firstName: "George"
      lastName: "Russel"
      phoneId: "1"
      phone_value: "97627445368"
      userID: 1
    }
]

What I am trying to achieve is something which has phone number and address as an example but would love to have all the attributes(phone, email, passport, employer, address etc) .

 {
      addressID: "1"
      address_value: "27 London Street E146AA"
      expDate: "2022-12-12T17:09:37.000Z"
      firstName: "George"
      lastName: "Russel"
      userID: 1
      phoneId: "1"
      phone_value: "97627445368"
      emailId:"1",
      email_value:"[email protected]"
      employerId:"1"
      employer_value:"QMUL"
      nationalityId:"1" 
      nationality:"Indian"
      passportId:"1" 
      passportNumber:"123445567"
    },

I was trying to do it with the following code as we have the userId as unique property and based on that I was trying to have the desired output but I cannot understand what am I missing in here.

result = data.reduce(function (r, a) {
        r[a.userID] = r[a.userID] || [];
        r[a.userID].push(a);
        return r;
    }, Object.create(null));
console.log(result);
const finalResult = [];
Object.keys(result).forEach(el => {
  result[el].forEach(el1 => {
    console.log(el1)
    //finalResult.push(...el1)
  })
})

CodePudding user response:

You were on the right track, just needs little improvement like using Object.values() instead of Object.keys(); and I used logical nullish assignment (??=)

const data = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"[email protected]"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const result = data.reduce(function(r, a) {
  r[a.userID] ??= []; // it's the same as r[a.userID] = r[a.userID] || [];
  r[a.userID].push({ ...a
  });
  return r;
}, {}); //Object.create(null)
let finalResult = [];
Object.values(result).forEach((arrObj) => {
  let result = {};
  Object.values(arrObj).forEach((obj) => {
    Object.assign(result, obj);
  });
  finalResult.push(result);
});
console.log(finalResult);

CodePudding user response:

For this type of problem, I would go with changing how the backend service operates; where it should doing a JOIN on the multiple tables so that you only get one object for each user, instead multiple.

That being said, I would accomplish this easiest with a map.

const result = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"[email protected]"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const newUserMap = new Map();

result.forEach((user) => {
    const { userID } = user;
    
    if (newUserMap.has(userID)) {
        const existingUser = newUserMap.get(userID);
        newUserMap.set(userID, {...existingUser, ...user});
    } else {
        newUserMap.set(userID, user);
    }
});

console.log(newUserMap);

Where the keys are the user ids and the values within them are the user objects. You are also able to run through each entry with a .forEach() loop; just like an array.

If you want to keep them as an array of objects, then you could accomplish this with something similar to a map, but it is quite costly in performance due to the .findIndex():

const result = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"[email protected]"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const newUserArray = [];

result.forEach((user) => {
    const { userID } = user;
    const existingUserIndex = newUserArray.findIndex(newUser => newUser.userID === userID);

    if (existingUserIndex !== -1) {
        newUserArray[existingUserIndex] = Object.assign(newUserArray[existingUserIndex], user);
    } else {
        newUserArray.push(user);
    }
});

console.log(newUserArray);

  • Related