How to update/add element of the array in JavaScript?
Why not use an associate array for persons['data']
, because .push()
just uses index arrays
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]
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).
JSFiddle here
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];
}
}
}
Arrays in javascript are indexed by numbers (or at least should be).
persons['data'].push(bob);
persons['data'].push(fill);
persons['data'].push(mark);
Using persons[2]
would give you {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.
[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).
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 filter the array to get values which match a predicate:
bob = persons.data.filter(function(person){
return person["name"] === 'Bob';
})[0];
EDIT:
Example of 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
You will need a query function like the following to help you find indices according to a property in your database: (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.
If using Underscore or lodash you already have a _.findIndex()
function that can be used instead:
var johnIndex = _.findIndex(persons.data, { name: 'John' });
2021 update: Using modern JavaScript you can replace the function with
const johnIndex = persons.data.findIndex(p => p.name === "John")