2017-07-09 200 views
0

如何基於另一個數組更新數組?更新列表基於JavaScript中的另一個列表

這是我試圖做到:


 
var ref = [ 
 
    { 
 
     "name": "Jack", 
 
     "title": "Manager", 
 
     "description": "", 
 
    }, 
 
    { 
 
     "name": "Steve", 
 
     "title": "CEO", 
 
     "description": "A test description", 
 
    } 
 
    ]; 
 

 
var elem = [ 
 
    { 
 
     "name": "Jack", 
 
     "title": "Manager", 
 
     "description": "", 
 
    }, 
 
    { 
 
     "name": "Steve", 
 
     "title": "CEO", 
 
     "description": "A test description", 
 
    } 
 
    ]; 
 

 

 
for (var i = 0; i < ref.length; i++) { 
 

 
\t ref.indexOf(elem[i]) === -1 ? ref.push(elem[i]) : console.log("This item already exists"); 
 

 
} 
 
console.log(ref); 
 
console.log(elem);
這個循環中,因爲其長度每個迭代後改變導致了錯誤。

我要的是,從elem object添加的每個元素,如果它不arr object當然存在停留在JOSN格式。在我的例子中,它不需要改變。

+0

所以你的2點輸入陣列是相同的,做你想修改? – RomanPerekhrest

+1

你沒有正確比較對象。雖然對象的內容可能相同,但您可能會有不同的引用。比較以及indexOf使用參考比較。 –

+0

如果您有兩個「傑克」,具有相同的「標題」,但在說明中略有不同,會發生什麼情況?換句話說,每個條目的主要關鍵是什麼? – trincot

回答

1

elem上運行循環會更好。你也不能比較的對象一樣,因爲引用會有所不同,所以你必須做深刻的檢查,這樣的事情應該工作:


 
var ref = [ 
 
    { 
 
     "name": "Jack", 
 
     "title": "Manager", 
 
     "description": "", 
 
    }, 
 
    { 
 
     "name": "Steve", 
 
     "title": "CEO", 
 
     "description": "A test description", 
 
    } 
 
    ]; 
 

 
var elem = [ 
 
    { 
 
     "name": "Jack", 
 
     "title": "Manager", 
 
     "description": "", 
 
    }, 
 
    { 
 
     "name": "Steve", 
 
     "title": "CEO", 
 
     "description": "A test description", 
 
    } 
 
    ]; 
 

 

 
for (var i = 0; i < elem.length; i++) { 
 
    var found = false; 
 
    for (var j=0; j<ref.length; j++){ 
 
     var count = Object.keys(elem[i]).length; 
 
     for(var key in elem[i]){ 
 
      if(ref[j][key] === elem[i][key]) 
 
       count--; 
 
     } 
 
     if (count === 0){ 
 
      found= true; 
 
      break; 
 
     } 
 
    } 
 
    if (!found) 
 
     ref.push(elem[i]); 
 
} 
 

 
console.log(ref); 
 
console.log(elem);

+0

謝謝,這工作,但任何更好的解決方案呢?我的意思是因爲3次循環! – GeoCom

+0

我認爲需要2個循環來比較兩個數組中的每個元素,而不使用indexOf。由於深入檢查,第三個數組是必需的。但是第三個循環的運行次數與對象中的鍵次數一樣多,我認爲這與數組中元素的數量相比是一個很小的數字。但是如果在對象中有一個標識鍵,則可以避免第三個循環,但是您沒有提到,因此我假設您需要比較對象中的所有鍵。 – Dij

1

爲了避免嵌套的循環,你可以建立一個Set與您在ref中的每個密鑰。比方說,你考慮的名字是確定關鍵,那麼它應該是這樣的:

ref = ref.concat(elem.filter(function (o) { 
    return !this.has(o.name) 
}, new Set(ref.map(o => o.name)))); 

所以,這個構建Set採取所有名稱中ref,傳遞,作爲thisfilter回調,這檢查每個elem條目是否具有集合中的name。如果是這樣,它將被filter排除。此篩選結果連接到ref

如果您確定關鍵的是別的東西,比如組合nametitle,然後調整是在最後map(.......)使用的功能,並在has()應用相同的邏輯。

下面是一個使用的nametitle組合作爲識別密鑰的小提琴(具有略微不同的樣本數據):

var ref = [{ 
 
    "name": "Jack", 
 
    "title": "Manager", 
 
    "description": "", 
 
}, { 
 
    "name": "Steve", 
 
    "title": "CEO", 
 
    "description": "A test description", 
 
}]; 
 

 
var elem = [{ 
 
    "name": "Jack", 
 
    "title": "Manager", 
 
    "description": "", 
 
}, { 
 
    "name": "Steve", 
 
    "title": "Programmer", 
 
    "description": "Java addict", 
 
}]; 
 

 
ref = ref.concat(elem.filter(function (o) { 
 
    return !this.has(JSON.stringify([o.name, o.title])) 
 
}, new Set(ref.map(o => JSON.stringify([o.name, o.title]))))); 
 

 
console.log(ref);
.as-console-wrapper { max-height: 100% !important; top: 0; }

相關問題