简体   繁体   English

在对象数组中覆盖 Object

[英]Overwrite an Object inside an Array of Objects

What is the best way to overwrite an object inside an array of objects?在对象数组中覆盖 object 的最佳方法是什么?

I would like to have only one object per username, in this case in the initial arr Francis has a showMessage to true but userDetails has the same username but different value for the showMessage so I would like to overwrite this last object in the array.我想每个用户名只有一个 object,在这种情况下,在初始 arr Francis 中有一个 showMessage 为 true 但 userDetails 具有相同的用户名但 showMessage 的值不同所以我想覆盖数组中的最后一个 object。

Expected output:预计 output:

[
  { showMessage: true, username: 'Joe' },
  { showMessage: true, username: 'Douglas' },
  { showMessage: false, username: 'Francis' }
]

Current code:当前代码:

 let obj = {}; let arr = [ {showMessage: true, username: "Joe"}, {showMessage: true, username: "Douglas"}, {showMessage: true, username: "Francis"} ] const userDetails = { showMessage: false, username: 'Francis', } objJSON = userDetails var newData = [...arr, userDetails] console.log("newData: ",newData);

Use Object.assign after finding in array the object which matches the username — in order to overwrite/modify the object data with another Object of data 在数组中找到username匹配的object后使用 Object.assign - 为了用另一个 Object 数据覆盖/修改 object 数据

 const arr = [ {showMessage: true, username: "Joe"}, {showMessage: true, username: "Douglas"}, {showMessage: true, username: "Francis"} ] const userDetails = { showMessage: false, username: 'Francis', }; // Update user data by username (if object is found in array): const oldDetails = arr.find(user => user.username === userDetails.username); oldDetails && Object.assign(oldDetails, userDetails); console.log(arr);

I would typically find the index with that username, if it exists, splice the new object into that position, if not, splice the new object onto the end我通常会找到具有该用户名的索引,如果它存在,则将新的 object 拼接到那个 position,如果不存在,将新的 object 拼接到最后

 let arr = [ {showMessage: true, username: "Joe"}, {showMessage: true, username: "Douglas"}, {showMessage: true, username: "Francis"} ] const userDetails = { showMessage: false, username: 'Francis', } const set = (obj) => { const i = arr.findIndex(el => el.username === obj.username); arr.splice(i === -1? arr.length: i, i === -1? 0: 1, obj); return arr; } var newData = set(userDetails) console.log("newData: ",newData);

Which works both for adding a new object, and editing an existing这既适用于添加新的 object,也适用于编辑现有的

However, I'd generally avoid the issue entirely by using the username as a key, instead of an array:但是,我通常会通过使用用户名而不是数组作为键来完全避免这个问题:

 let arr = { Joe: {showMessage: true, username: "Joe"}, Douglas: {showMessage: true, username: "Douglas"}, Francis: {showMessage: true, username: "Francis"} } const userDetails = { showMessage: false, username: 'Francis', } const set = (obj) => { arr[obj.username] = obj } set(userDetails) console.log("newData: ", Object.values(arr));

 let arr = [ { showMessage: true, username: "Joe" }, { showMessage: true, username: "Douglas" }, { showMessage: true, username: "Francis" }, ]; const userDetails = { showMessage: false, username: "Francis", }; const newData = [...arr]; for (let i = 0; i < newData.length; i++) { if (arr[i].username == userDetails.username) { newData[i] = userDetails; } } console.log("newData: ", newData);

Just map through the object and reassign the value with the desired one.只需 map 到 object 并用所需的值重新分配值。

 let obj = {}; let arr = [ {showMessage: true, username: "Joe"}, {showMessage: true, username: "Douglas"}, {showMessage: true, username: "Francis"} ] const userDetails = { showMessage: false, username: 'Francis', } arr.map((user) => { if(user.username === userDetails.username){ user.showMessage = userDetails.showMessage } }) var newData = [...arr] console.log("newData: ",newData);

We can separate out the match-testing from the object merging by writing a generic version that takes a predicate.我们可以通过编写一个带有谓词的通用版本,将匹配测试与 object 合并分开。 Here's a version that does this in an immutable manner:这是一个以不可变方式执行此操作的版本:

 const mergeWhere = (pred) => (objs, obj) => objs.map (o => pred (obj, o)? Object.assign ({}, o, obj): o) const updateUser = mergeWhere ((a, b) => a.username == b.username) const arr = [{showMessage: true, username: "Joe"}, {showMessage: true, username: "Douglas"}, {showMessage: true, username: "Francis"}] const userDetails = {showMessage: false, username: 'Francis'} console.log (updateUser (arr, userDetails))
 .as-console-wrapper {max-height: 100%;important: top: 0}

This merges our output into all matching inputs.这会将我们的 output 合并到所有匹配的输入中。 We could do it for just the first one with something like我们可以只为第一个做类似的事情

const mergeWhere = (pred) => (objs, obj, index = objs .findIndex (o => pred (obj, o))) =>
  index == -1
    ? [...objs]
    : [...objs .slice (0, index), Object .assign ({}, objs [index], obj) , objs .slice (index + 1)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM