如何在JavaScript中更新/添加数组的元素

How to update/add element of the array in JavaScript?

本文关键字:添加 数组 元素 更新 JavaScript      更新时间:2023-09-26

如何更新/添加数组中的元素?

var persons = {
    data: []
};
var bob = {name: 'Bob', age: 15};
var fill = {name: 'Fill', age: 20};
var mark = {name: 'Mark', age: 19};
var john = {name: 'John', age: 4};
persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);
persons['data'].push(john);
var updatedJohn = {name: 'John', age: 100};
if (!persons['data'][updatedJohn.name]){
    persons['data'].push(updatedJohn);
} else {
    persons['data'][updatedJohn.name] = updatedJohn; // this line doesn't work
}

如果元素John已经存在,我不知道如何更新数组的元素。

更新

jsFiddle示例

您需要一个如下的查询函数来帮助您根据数据库中的属性查找索引:(JSFiddle)

function findIndexByProperty(data, key, value) {
    for (var i = 0; i < data.length; i++) {
        if (data[i][key] == value) {
            return i;
        }
    }
    return -1;
}
var johnIndex = findIndexByProperty(persons.data, 'name', 'John');
if (johnIndex > -1) {
    persons.data[johnIndex] = updatedJohn;
} else {
    persons.data.push(updatedJohn);
}

请注意,这只返回名为John的第一条记录。在有多个这样的记录的情况下,你需要决定你希望它做什么——更新所有记录?这类问题就是为什么数据库通常有唯一的密钥来识别记录。

如果使用Underscore或lodash,您已经有了可以使用的_.findIndex()函数:

var johnIndex = _.findIndex(persons.data, { name: 'John' }); 

2021更新:使用现代JavaScript,您可以用替换该功能

const johnIndex = persons.data.findIndex(p => p.name === "John")

为什么不为persons['data']使用关联数组,因为.push()只使用索引数组

var persons = {
   data: {}
};
...
persons['data'][john.name] = john;
...
var updatedJohn = {name: 'John', age: 100};
// if statement isn't neccesary no more bc
// if the index is there it will override it and if not
// it will create a new index
persons['data'][updatedJohn.name] = updatedJohn;

这行对您不起作用,因为person数组是由整数persons['data'].push()而不是字符串persons['data'][stringIndex]索引的。

您可以为每个现有的人创建一个查找表,如果它不在其中,您可以将其推送到persons.data中并在查找表中创建一个新条目,否则您可以在不破坏给定值引用的情况下重写整个person对象。(我写了一篇评论来解释这一部分)。

JSFiddle此处

var persons = {
    data: []
};
var bob = {name: 'Bob', age: 15};
var fill = {name: 'Fill', age: 20};
var mark = {name: 'Mark', age: 19};
var john = {name: 'John', age: 4};
persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);
persons['data'].push(john);
var personsHash = {};
// store an external reference for each persons
for (var i = 0, l = persons.data.length; i < l; i++) {
    personsHash[persons.data[i].name] = persons.data[i];
}
var updatedJohn = {name: 'John', age: 100};
if (!personsHash[updatedJohn.name]){
    personsHash[updatedJohn.name] = updatedJohn;
    persons['data'].push(updatedJohn);
} else {
    var key;
    var person = personsHash[updatedJohn.name];
    // comment if you don't want a full rewrite but just an update of attributes
    /**/
    for (key in person) {
        delete person[key];
    }
    /**/
    for (key in updatedJohn) {
        if (updatedJohn.hasOwnProperty(key)) {
            person[key] = updatedJohn[key];
        }
    }
}

javascript中的数组是通过数字索引的(或者至少应该是)。

persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);

使用persons[2]会给你{名字:"Mark",年龄:19岁}。

虽然Javascript非常灵活,你可以像@Sasa中那样回答并使用字符串索引,但如果你这样做,你可能会被其他开发人员拒绝,因为这是一种非常糟糕的做法。

[添加]想想这些奇怪和意外行为的例子:

var ary = [];
ary[0] = false;
ary['using string indexes in javascript arrays is stupid'] = true;
console.log('pop should return the last added element', ary.pop()); //  false - WTF?
console.log('lastIndexOf should be 1?', ary.lastIndexOf(true)); // -1 WTF?

Javascript中的数组应该用作堆栈。想象一下一堆牌,你可以添加(推)或拿走(拉)牌,但你不知道哪张牌在哪里(除非你作弊)。

如果你想要一个按姓名列出的人员列表,你可以使用一个对象来存储人员:

persons.data = {};
persons['data']['Bob'] = bob;

或者,您可以过滤数组以获得与谓词匹配的值:

bob = persons.data.filter(function(person){
  return person["name"] === 'Bob';
})[0];

编辑:

创建或查找人员的功能示例:

var persons = { data : [] }
persons.data.push({ name: 'Bob', age: 10 })
// returns the index of the newly added person
persons.addOrReplace = function(new_person, attr) {
    var attr = attr || 'name';
    var data = this.data;    
    for (var i = 0; i < data.length; i++) {
      if (data[i][attr] === new_person[attr]) {
        data[i] = new_person;
        return i;
      }
    }   
    return this.data.push(new_person);
}
persons.addOrReplace({ name: 'Bob', age: 11 });
console.log(persons.data.length); // 1
console.log(persons.data[0].age); // 11
persons.addOrReplace({ name: 'Joe', age: 11 });
console.log(persons.data.length); // 2
console.log(persons.data[persons.data.length -1].name); // Joe

尝试迭代persons对象的元素,如果存在同名成员,则更新该元素,如果不存在,则向数组中推送一个新元素。使用新变量exists来检查该成员是否存在。

以下是您可以做的:

var persons = {
    data: []
};
var bob = {name: 'Bob', age: 15};
var fill = {name: 'Fill', age: 20};
var mark = {name: 'Mark', age: 19};
var john = {name: 'John', age: 4};
persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);
persons['data'].push(john);
var updatedJohn = {name: 'John', age: 100};
var exists = 0;
for (var i=0; i<persons['data'].length; i++) {
    if (persons['data'][i].name == updatedJohn.name) {
        persons['data'][i].age = updatedJohn.age;
        exists = 1;
    }
}
if (exists === 0)
    persons['data'].push(updatedJohn);

这是你更新的小提琴:http://jsfiddle.net/t4kjgkcn/3/

function addOrUpdate(arr, comp, update) {
  if (arr) {
    var updated = false;
    arr.map(function(e, i) {
      var found = e[comp] == update[comp];
      if (found) {
        angular.extend(arr[i], update);
        updated = true;
      }
    });
    if (!updated) {
      arr.push(update);
    }
  }
}
//example
var a = [{
  id: 1,
  name: 'a'
}, {
  id: 2,
  name: 'b'
}, {
  id: 3,
  name: 'c'
}];
addOrUpdate(a, "id", {
  id: 4,
  name: 'e3333'
});
//looks for an elemnent with id=4, doesnt find, and adds it
addOrUpdate(a, "id", {
  id: 4,
  name: 'e5555'
});
//this time it will find and update the name