如何在 JavaScript 中更新/添加数组元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26700310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to update/add element of the array in JavaScript?
提问by Alex
How can I update/add element in the array?
如何更新/添加数组中的元素?
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
}
I can't figure out how to update an element of the array if element John
already exist.
如果元素John
已经存在,我无法弄清楚如何更新数组的元素。
UPDATE
更新
采纳答案by Stuart
You will need a query function like the following to help you find indices according to a property in your database: (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);
}
Note that this only returns the first record with name John. You will need to decide what you want it to do in the case of multiple such records - update all of them? This kind of problem is why databases usually have unique keys to identify records.
请注意,这仅返回名为 John 的第一条记录。您需要决定在多个此类记录的情况下您希望它做什么 - 更新所有记录?这种问题就是为什么数据库通常有唯一的键来标识记录。
If using Underscore you already have a _.findIndex()
function that can be used instead:
如果使用 Underscore,您已经拥有一个_.findIndex()
可以替代的函数:
var johnIndex = _.findIndex(persons.data, { name: 'John' });
回答by Jay Harris
Why not use an associate array for persons['data']
, because .push()
just uses index arrays
为什么不使用关联数组 for 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;
The line didn't work for you because the person array was indexed by integers persons['data'].push()
instead of strings persons['data'][stringIndex]
该行对您不起作用,因为 person 数组是由整数persons['data'].push()
而不是字符串索引的persons['data'][stringIndex]
回答by max
Arrays in javascript are indexed by numbers (or at least should be).
javascript 中的数组由数字索引(或至少应该是)。
persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);
Using persons[2]
would give you {name: 'Mark', age: 19}.
使用persons[2]
会给你 {name: 'Mark', age: 19}。
While Javascript is so flexible that you can do as in @Sasa answer and use string indexes you may get kneecapped by other developers if you do since this is a VERY BAD PRACTICE.
虽然 Javascript 非常灵活,您可以像在@Sasa 答案中那样使用字符串索引,但如果您这样做,您可能会被其他开发人员绊倒,因为这是一种非常糟糕的做法。
[ADDED]Consider these examples of weird and unexpected behaviour:
[添加]考虑这些奇怪和意外行为的例子:
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?
Arrays in Javascript should be used as stacks. Think of a stack of cards, you either add (push) or take away cards (pull) but you don′t know which card is where (unless you′re cheating).
Javascript 中的数组应该用作堆栈。想想一堆卡片,你要么加(推)要么拿走(拉),但你不知道哪张牌在哪里(除非你在作弊)。
If you want a list of persons by name you would use an object to store persons:
如果您想要按姓名列出人员列表,您可以使用对象来存储人员:
persons.data = {};
persons['data']['Bob'] = bob;
Or alternatively you could filterthe array to get values which match a predicate:
或者,您可以过滤数组以获取与谓词匹配的值:
bob = persons.data.filter(function(person){
return person["name"] === 'Bob';
})[0];
EDIT:
编辑:
Exampleof a function that would create or find a person:
创建或查找人员的函数示例:
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
回答by webeno
Try iterating through the elements of the persons
object, update the element if a member with the same name exists, if it doesn't, push a new element to the array. Use a new variable exists
to check if the member existed.
尝试遍历persons
对象的元素,如果存在同名成员,则更新元素,如果不存在,则将新元素推送到数组中。使用新变量exists
检查成员是否存在。
Here is what you could do:
您可以这样做:
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);
Here is you updated fiddle: http://jsfiddle.net/t4kjgkcn/3/
这是你更新的小提琴:http: //jsfiddle.net/t4kjgkcn/3/
回答by axelduch
You can make a lookup table for every existing person if it's not in it, you push it in persons.data and create a new entry in the lookup table, else you rewrite full the person object without breaking the value's reference given. (I wrote a comment to explain this part).
您可以为每个现有人员创建一个查找表,如果它不在其中,则将其推送到 people.data 中并在查找表中创建一个新条目,否则您可以在不破坏给定值的引用的情况下完全重写 person 对象。(我写了一条评论来解释这部分)。
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];
}
}
}
回答by Or Gal
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