无法使用扩展运算符替换对象

时间:2019-04-22 11:21:14

标签: javascript angular reactjs ecmascript-6

我想使用扩展运算符将现有对象替换为新的更新字段。但是我没有得到正确的结果。

下面是我的两个对象。

let obj1 = [
  {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
]

let newObj = {
  "id": 3,
  "name": "Gary",
  "age": 23,
  "email": "gary@gmail.com"
}

我可以使用.map做到这一点。下面是我的代码。

let result = obj1.map(item => {
  if (item.id === newObj.id) {
    return {...item, ...newObj};
  }
  return item;
});

但是我不想运行循环,而只希望通过传播算子来实现。

传播实例。这不起作用。它不是替换对象。而是再创建一个。

[...obj1,  newObj];

有人可以帮我吗?

JSBIN CODE SNIPPET

5 个答案:

答案 0 :(得分:3)

使用Object.assign

  

Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

let obj1 = [
  {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
]

let newObj = {
  "id": 3,
  "name": "Gary",
  "age": 23,
  "email": "gary@gmail.com"
}

Object.assign(obj1[2], newObj);

console.log(obj1)

使用.find()获取目标obj

let obj1 = [
  {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
]

let newObj = {
  "id": 3,
  "name": "Gary",
  "age": 23,
  "email": "gary@gmail.com"
}

const targetObj = obj1.find(obj => obj.id === newObj.id)

Object.assign(targetObj, newObj);

console.log(obj1)

答案 1 :(得分:2)

传播语法不会像您使用它那样替换数组中的对象。使用地图是最简单易懂的方法。但是,如果要使用spread syntax,则首先需要找到要替换的索引,然后在数组上使用切片

let obj1 = [
  {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
]

let newObj = {
  "id": 3,
  "name": "Gary",
  "age": 23,
  "email": "gary@gmail.com"
}

const idx = obj1.findIndex(item => item.id === newObj.id);

obj1 = [...obj1.slice(0, idx), newObj, ...obj1.slice(idx + 1)];

console.log(obj1);

答案 2 :(得分:0)

Spread运算符很神奇,但是它不会做任何您想做的事情,您将不得不遍历并替换对象。我宁愿选择map(),也不愿做find()。使用Object.assign()来实现您想要的。

let obj1 = [
  {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
]

let newObj = {
  "id": 3,
  "name": "Gary",
  "age": 23,
  "email": "gary@gmail.com"
}


let foundOb = obj1.find(e => e.id === newObj.id);

Object.assign(foundOb, newObj)
console.log(obj1)

答案 3 :(得分:0)

您应该通过id通过以下方式标准化数据:

obj1 = {
   1: {
    "id": 1,
    "name": "Michel",
    "age": 34,
    "email": "michel@gmail.com"
  },
  2: {
    "id": 2,
    "name": "Abby",
    "age": 40,
    "email": "abby@gmail.com"
  },
  3: {
    "id": 3,
    "name": "Gary",
    "age": 40,
    "email": "abby@gmail.com"
  }
}

newObj = {
  3: {
    "id": 3,
    "name": "Gary",
    "age": 23,
    "email": "gary@gmail.com"
  }
}

通过这种方式,您可以使用传播运算符:

 { ...obj1, ...newObj }

为了规范化,您可以通过以下方式使用reduce函数:

const normalized = obj1.reduce((result, obj) => ({ ...result, [obj.id]: obj }), {})

答案 4 :(得分:0)

您不能以这种方式使用扩展语法。一种解决方案是找到要用id属性替换的对象的索引,然后可以将扩展语法与slice方法一起使用,以创建带有替换对象的新数组。

let obj1 = [{"id":1,"name":"Michel","age":34,"email":"michel@gmail.com"},{"id":2,"name":"Abby","age":40,"email":"abby@gmail.com"},{"id":3,"name":"Gary","age":40,"email":"abby@gmail.com"}]
let newObj = {"id":3,"name":"Gary","age":23,"email":"gary@gmail.com"}

const index = obj1.findIndex(({id}) => id == newObj.id)
const result = [...obj1.slice(0, index), newObj, ...obj1.slice(index + 1)]

console.log(result)