[Vuejs]-Is there a neater way to transform an array of objects

0👍

Since you only need to change a property inside contact, you can use object destructuring with rest, to extract contact from the rest of the object.

Now you can spread the rest of the object into the new one, create a new contact property, spread the contents of the original content into it, and override the phone property.

function guestList(getSelectedGuests) {
  return getSelectedGuests.map(({ contact, ...rest }) => ({
    ...rest,
    contacts: {
      ...contact,
      phone: contact.phone.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, ''),
    }
  }));
}

const users = [{"id":"1","name":{"givenNames":"SpongeBob","last":"SquarePants"},"contact":{"email":"","phone":"+1 123-1231234"}},{"id":"2","name":{"givenNames":"Patrick","last":"Star"},"contact":{"email":"test2@test.com","phone":"+1 123-123-1234"}},{"id":"3","name":{"givenNames":"Eugene Harold","last":"Krabs"},"contact":{"email":"test3@test.com","phone":""}}];

const result = guestList(users);

console.log(result);

If you need to do a lot of immutable transformations, you might want to consider Immer. Immer allows you to use simple mutating code, and it ensures immutability using Proxies.

const { produce } = immer;

function guestList(getSelectedGuests) {
  return getSelectedGuests.map(user => produce(user, draft => {
    draft.contact.phone = user.contact.phone.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, '')
  }));
}

const users = [{"id":"1","name":{"givenNames":"SpongeBob","last":"SquarePants"},"contact":{"email":"","phone":"+1 123-1231234"}},{"id":"2","name":{"givenNames":"Patrick","last":"Star"},"contact":{"email":"test2@test.com","phone":"+1 123-123-1234"}},{"id":"3","name":{"givenNames":"Eugene Harold","last":"Krabs"},"contact":{"email":"test3@test.com","phone":""}}];

const result = guestList(users);

console.log(result);

console.log(result[0] === users[0]); // false - a new object was created
<script src="https://unpkg.com/immer/dist/immer.umd.js"></script>

0👍

Well, as long as you don’t use a library exposing Immutable objects implementation, this is the kind of code you have to write. Depending upon the JS dialect you have access to, you can write slightly shorter code, but the buld is still there:

guestList() {
  return this.getSelectedGuests.map(user => ({
    user.id,
    user.name,
    contact: {
        user.contact.email,
        phone: user.contact.phone.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, ''),
    }
  }));
}

If you want to work with immutability, I would strongly advise to have a look at something like Immutable.js (probably the one with the most diffusion) or Seamless Immutable (which has far less diffusion, but I like it a lot).

0👍

You can’t avoid visiting each user because you have to change each user’s contact property.

I am only changing the number of the contact object for each user so
it feels a little redundant to go through every other value to create
a new formatted array.

You can use spread syntax to copy object properties without explicitly copying them.

I also added hyphen - and whitespace character \s to the regex to get the desired output.

const users = [{ id: "1", name: { givenNames: 'SpongeBob', last: 'SquarePants', }, contact: { email: '', phone: '+1 123-1231234' }, }, { id: "2", name: { givenNames: 'Patrick', last: 'Star', }, contact: { email: 'test2@test.com', phone: '+1 123-123-1234', }, }, { id: "3", name: { givenNames: 'Eugene Harold', last: 'Krabs', }, contact: { email: 'test3@test.com', phone: '', }, } ];

let result = users.map(user => ({
  ...user,
  contact: {
    ...user.contact,
    "phone": user.contact.phone.replace(/[&\/\\#,+()$~%.'":*?<>{}-\s]/g, '')
  }
}));

console.log(result);

In most cases, you shouldn’t be concerned about creating new arrays because JavaScript and platforms it runs on optimize for such scenarios.

But if you want to modify the array in-place, you can use forEach() to do that.

const users = [{ id: "1", name: { givenNames: 'SpongeBob', last: 'SquarePants', }, contact: { email: '', phone: '+1 123-1231234' }, }, { id: "2", name: { givenNames: 'Patrick', last: 'Star', }, contact: { email: 'test2@test.com', phone: '+1 123-123-1234', }, }, { id: "3", name: { givenNames: 'Eugene Harold', last: 'Krabs', }, contact: { email: 'test3@test.com', phone: '', }, } ];

users.forEach(user => {
  user.contact.phone = user.contact.phone.replace(/[&\/\\#,+()$~%.'":*?<>{}-\s]/g, '');
});

console.log(users);

Leave a comment