2014-11-02 56 views
7

如何更新/添加數組中的元素?如何在JavaScript中更新/添加數組元素?

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已經存在如何更新數組的元素。

UPDATE

jsFiddle example

+0

如果兩個人具有相同的名稱,會發生什麼? – axelduch 2014-11-02 14:30:23

+0

在這種情況下,我們需要更新一個存在的人(約翰)。這個數組就像一個'Set'。 – Alex 2014-11-02 14:30:55

回答

4

您將需要像下面這樣的查詢函數來幫助您根據數據庫中的屬性找到索引:(JSFiddle

function getIndexByProperty(data, key, value) { 
    for (var i = 0; i < data.length; i++) { 
     if (data[i][key] == value) { 
      return i; 
     } 
    } 
    return -1; 
} 

var johnIndex = getIndexByProperty(persons.data, 'name', 'John'); 
if (johnIndex > -1) { 
    persons.data[johnIndex] = updatedJohn; 
} else { 
    persons.data.push(updatedJohn); 
} 

注意,這僅返回與名叫約翰的第一條記錄。您需要決定在多個此類記錄的情況下要執行的操作 - 更新所有這些記錄?這種問題是爲什麼數據庫通常具有唯一的鍵來識別記錄。

1

陣列以JavaScript由數字索引(或至少應該是)。

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

使用persons[2]會給你{名稱: '馬克',年齡:19}。

雖然JavaScript是非常靈活,你可以做在@Sasa答案,並使用您可以通過其他開發人員,如果你這樣做,因爲這是一個非常不好的做法得到kneecapped字符串索引。

[加] 考慮的奇怪和意外的行爲,這些例子:在Javascript

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? 

陣列應作爲堆棧。想想一堆牌,你可以添加(推)或拿走牌(拉),但你不知道哪個牌在哪裏(除非你是在作弊)。

如果你想通過名稱的人員名單,你會使用一個對象來存儲人數:

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

或者你也可以filter陣列拿到賽謂詞其值:

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

編輯:

Example一個功能,將創建或找到一個人:

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 
+0

這是非常糟糕的做法的原因是,既然你有對象完全適合字典(鍵值,也稱爲散列或關聯數組),我們期望數組按照插入的順序進行數字索引。 – max 2014-11-02 14:40:30

+0

如果使用'filter'方法,然後嘗試使用'bob = updatedBob'更改記錄,'persons.data'內的記錄將不會更新。 – Stuart 2014-11-02 14:40:34

+0

@Stuart。你錯了,對象是通過引用傳遞的。 http://jsfiddle.net/4xp02cuu/ – max 2014-11-02 15:01:03

2

爲什麼不使用的副陣列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; 

因爲人陣是由整數persons['data'].push()而不是字符串persons['data'][stringIndex]

索引的行沒有爲你工作
+0

爲什麼投票沒有推理? – 2014-11-02 14:46:40

+0

在JavaScript中使用「關聯數組」是一個不錯的主意,因爲每個人都希望數組被索引。如果您想要一個鍵值存儲,請使用對象。 – max 2014-11-02 14:53:30

+0

@papirtiger我不知道是誰教你的,但關聯數組(對象)在任何語言中都非常有用,而不僅僅是js。爲什麼我期望我用聯繫人鍵創建的數組是數字? – 2014-11-02 15:00:29

1

嘗試遍歷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/

+0

將無法​​正常工作 – Stuart 2014-11-02 14:51:19

+0

@Stuart你能澄清嗎?我在這裏測試了它,它爲我工作:http://jsfiddle.net/95d9oLkq/1/ – webeno 2014-11-02 14:52:01

+0

嘗試'console.log(persons.data)' - 你已經爲數據庫添加了'updatedJohn'的副本,記錄,沒有名稱「約翰」 – Stuart 2014-11-02 14:55:44

1

你可以做一個查找表爲每個現有的人,如果不是它,你把它的人.data並在查找表中創建一個新條目,否則,您會重寫完整的person對象而不會破壞給定的值的引用。 (我寫了一條評論來解釋這部分)。

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]; 
     } 
    } 
} 
+0

如果老約翰存在,我不需要添加一個全新的約翰。在那種情況下,我只需要用新的約翰替換舊約翰。就這樣。但是你的解決方案確實添加了新的John對象。 – Alex 2014-11-02 14:55:07

+0

是的,只有當它不存在時纔會添加。我只是用一種完全重寫舊約翰的方式,但從不打破對象的引用(不使用'=') – axelduch 2014-11-02 14:57:29

+0

http://jsfiddle.net/9x4vv7vq/3/ – Alex 2014-11-02 15:06:14

0

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

相關問題