如何使用引用编辑对象的值?

时间:2018-08-12 10:22:40

标签: javascript

我有一个大对象数组persons

persons = [{name:'john1'}, {name:'john2'},...]

我迭代了数组并找到了我想要编辑的对象

objectToEdit = persons .find((person)=>person.name==='john1')

现在,我以不变的方式(someOtherPerson = {name:'johnxx'})创建了一个编辑对象

objectFinal = {...objectToEdit, someOtherPerson}

现在,我想将此objectFinal替换为objectToEdit数组中的persons,而不必再次遍历该数组。但是执行objectToEdit =objectFinal只会将objectToEdited的引用分配给objectToEdit,而不会在persons数组中进行任何更改

是否有一种无需遍历数组的干净方法即可实现?

修改

在此示例中,人员中的对象仅握有一个键(即name)。这是为了使问题最小化。在我的项目中,我有30多个键。

4 个答案:

答案 0 :(得分:3)

如果要避免使原始数组中的对象发生变异,则可以改用.findIndex,然后在该索引处重新分配数组中的项目:

const persons = [{name:'john1'}, {name:'john2'}];
const objectToEditIndex = persons.findIndex((person) => person.name === 'john1');
const someOtherPerson = {name:"johnxx"};
persons[objectToEditIndex] = {
  ...persons[objectToEditIndex],
  ...someOtherPerson
};
console.log(persons);

答案 1 :(得分:3)

如果要在列表中编辑对象,请使用Array.prototype.some

var persons = [{
  name: 'john1'
}, {
  name: 'jack5'
}]

var someOtherPerson = {
name: 'johnxx'
}

persons.some(function(person) {
  // if condition, edit and return true
  if (person.name === 'john1') {
    // use Object.keys to copy properties
    Object.keys(someOtherPerson).forEach(function(key) {
      person[key] = someOtherPerson[key]
    })
    // or use assign to merge 2 objects
    Object.assign(person, someOtherPerson);
    return true // stops iteration
  }
})

console.log(JSON.stringify(persons))

答案 2 :(得分:0)

这样做:

objectFinal = {...objectToEdit, someOtherPerson}

您将丢失对原始objectToEdit对象的引用。要对其进行编辑,您可以

`objectToEdit.value = otherValue`.

PS:话虽如此,您只会丢失对第一级对象的引用。如果该对象包含另一个对象或数组,则您具有引用:

objectFinal.innerObject.value = otherValue;

答案 3 :(得分:0)

  在个人中,

{name:'john1'}应替换为{name:“ johnxx”}

persons重新分配给以新值映射的persons数组:

let persons = [{name:'john1'}, {name:'john2'}];
persons = persons.map( v => v.name === "john1" ? {name: "johnxx"} : v );
console.log(persons);

或者,如果您担心性能,可以将Array.spliceArray.findIndex组合使用

  

findIndex方法每执行一次回调函数   数组中的数组索引0..length-1(含),直到找到一个   其中,callback返回真实值(强制转换为true的值)。   如果找到了这样的元素,则立即返回findIndex   对于该迭代

let persons = [{name:'john1'}, {name:'john2'}];
persons.splice(persons.findIndex( v => v.name==="john1" ), 1, {name:'johnxx'});
console.log(persons);

或使用实用程序方法(大数组(1,000,000个元素)的片段,并带有性能计时器)

// replacer method
const replace = (obj, [key, value], replacement) => {
   obj.splice(persons.findIndex( v => v[key] === value ), 1, replacement);
   return obj;
}

// create a large array (this may take some extra time)
let persons = Array.from({length: 1000000}).map(v => 
  ({name: Math.floor(100000 + Math.random() * 1000000000).toString(16)}) );

// pick an entry
const someEntry = Math.floor(persons.length * Math.random());
const entry = Object.entries(persons[someEntry])[0];

console.log("before:", persons[someEntry]);
const t = performance.now();

// replacement call here
console.log("after:", replace(persons, entry, {name: "johnxx"})[someEntry]);
console.log("replacement took:", `${((performance.now() - t)/1000).toFixed(3)} sec`);