有没有更整洁的方法来转换对象数组

时间:2019-10-29 21:29:06

标签: javascript arrays vue.js

我正在尝试转换一个数组,只更改其中一个值。有没有更整洁的方法?

我已附上我尝试过的代码。它可以工作,但是我只是为每个用户更改联系人对象的数量,因此遍历所有其他值来创建新的格式化数组感觉有点多余。我该如何仅替换联系电话而不进行任何操作?

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: '',
    },
  },
];

我的代码:

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

输出:

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

3 个答案:

答案 0 :(得分:0)

好吧,只要您不使用公开不可变对象实现的库,就必须编写这种代码。根据您可以访问的JS方言,您可以编写稍短的代码,但是buld仍然存在:

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

如果您想使用不变性,我强烈建议您看一下类似Immutable.js(可能是扩散最多的那个)或Seamless Immutable(扩散少得多的东西),我非常喜欢。)

答案 1 :(得分:0)

您不可避免地要访问每个用户,因为您必须更改每个用户的contact属性。

  

我只是为每个用户更改联系人对象的数量,所以   遍历所有其他价值来创造感觉有点多余   一个新的格式化数组。

您可以使用spread syntax复制对象属性,而无需显式复制它们。

我还在正则表达式中添加了连字符-和空格字符\s,以获得所需的输出。

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);

在大多数情况下,您不必担心创建新数组,因为JavaScript和平台可以针对此类情况进行优化。

但是,如果要就地修改数组,可以使用forEach()进行修改。

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);

答案 2 :(得分:0)

由于只需要更改contact内的属性,因此可以将object destructuringrest结合使用,以从对象的其余部分提取contact

现在您可以将对象的其余部分spread放入新对象,创建新的contact属性,将原始content的内容散布到其中,并覆盖{{ 1}}属性。

phone

如果您需要进行很多不可变的转换,则可能需要考虑Immer。 Immer允许您使用简单的变异代码,并使用Proxies确保不变性。

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);
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