2017-08-17 60 views
0

合併obj1和obj2等對象以在javascript中獲取obj3。使用不同的鍵但是具有相同的值合併兩個無序對象?

obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}] 
obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}] 

obj3 = [{fruit_name: 'apple', color: 'red', sweetness: 5},{fruit_name: 'banana', color:'yellow', sweetness: 4},{fruit_name: 'watermelon', color:'green', sweetness: 3}] 
+2

您的「對象」示例在語法上不正確。你是否打算使用大括號'{'/'[''交換? – ASDFGerte

+0

是的,我不小心將它們交換 – DanFragoso

+1

你的問題是什麼?您只發布了一條說明。你試圖自己解決這個問題嗎? – Bergi

回答

0

可以第一通過合併創建hashtable類似對象使用#forEach然後分機RACT使用#map()功能所需的陣列 - 看演示如下:

var obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}], 
 
    obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}], hash = {}; 
 

 
// function to create a hashtable 
 
function classify(e) { 
 
    if(hash[e.fruit] || hash[e.fruit_name]) { 
 
    Object.keys(e).forEach(function(c){ 
 
     hash[e.fruit || e.fruit_name][c] = e[c]; 
 
    }); 
 
    } else { 
 
    hash[e.fruit_name || e.fruit] = e; 
 
    } 
 
} 
 

 
// add to hash 
 
obj1.forEach(classify); 
 
obj2.forEach(classify); 
 

 
// extract the result 
 
var obj3 = Object.keys(hash).map(function(e){ 
 
    delete hash[e]['fruit']; 
 
    return hash[e]; 
 
}); 
 

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

+1

這也是一個相當不錯的解決方案 – DanFragoso

+0

謝謝,這將適用於所有類似的數據結構 - 你只需要知道*唯一識別一個數組中的元素的關鍵(這裏它是'fruit'或'fruit_name')... – kukkuz

+0

哈希值有點浪費... – tibetty

0

您的數據結構不正確。你不能在數組中保存「'水果:'西瓜'」(鍵,值對)。

它將給出一個錯誤:Uncaught SyntaxError: Unexpected token :

我假設你正在嘗試做的是:

obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}] 
 
    obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}] 
 
    obj3 = []; 
 
    
 
for (i = 0; i < obj1.length; i++) { 
 
    for (j = 0; j < obj2.length; j++) { 
 
    if (obj1[i].fruit === obj2[j].fruit_name) { 
 
     var temp = { 
 
     fruit_name: obj2[j].fruit_name, 
 
     color: obj2[j].color, 
 
     sweetness: obj1[i].sweetness 
 
     } 
 
     obj3.push(temp); 
 
    } 
 
    } 
 
} 
 

 
console.log(obj3);

+0

我修正了這個例子 – DanFragoso

+0

編輯了代碼。 – user3815252

+0

謝謝,這工作 – DanFragoso

0
let obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}]; 
let obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}]; 

function regulate(a) { 
    return a.map(v => { 
    if (v.fruit) { 
     v.fruit_name = v.fruit; 
     delete v.fruit; 
    } 
    return v; 
    }); 
} 


let a = [].concat(regulate(obj1), regulate(obj2)); 

let merged = []; 
a.reduce((m, v) => { 
    let f = m.filter(v2 => v2.fruit_name === v.fruit_name); 
    if (f.length > 0) { 
    Object.assign(f[0], v); 
    } else { 
    m.push(v); 
    } 
    return m; 
}, merged); 

console.log(merged); 
+0

修改我的代碼以反映原始請求。 – tibetty

+0

我的解決方案是一般的,但方式太浪費只有2陣列的情況... – tibetty

0

這是相當簡單的放在一起的通用功能合併對象的兩個陣列使用共享密鑰。最簡單的方法是使用基於關聯數組的映射,如下所示。請注意,您可以使用此例程解決類似類型的任何問題,但它絕對適用於您的數據 - 請參閱最後鏈接的JSFiddle。

(ETA:共享密鑰只加一次,與作爲KEY1提供的名稱;如果希望第二鍵在輸出捲起,只需交換對函數的自變量)

obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}]; 
obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}]; 

function mergeObjectArrays(array1, key1, array2, key2) { 
    var map = []; // an associative array/hashtable 
    var arrayValue, mapValue, propertyNames, propertyName, propertyValue; 

    // 1. Loop over one array, populating the map by each object's specified key 
    for(var x = 0; x < array1.length; x++) { 
    array1Value = array1[x]; 
    map[array1Value[key1]] = array1Value; 
    map.push(array1Value); 
    } 

    // 2. Loop over the other array, matching on the provided keys 
    for(var x = 0; x < array2.length; x++) { 
    arrayValue = array2[x]; 
    mapValue = map[arrayValue[key2]]; 

    if (typeof(mapValue) != 'undefined') { // add all missing non-keyed properties to the mapped/merged object 
     propertyNames = Object.keys(arrayValue); 
     for (var y = 0; y < propertyNames.length; y++) { 
      propertyName = propertyNames[y]; 
      if (propertyName != key1 && propertyName != key2) { // .. as that shared value is already added 
      propertyValue = arrayValue[propertyName]; 
      mapValue[propertyName] = propertyValue; 
      } 
     }  
    } 
    else { // it's missing from the mapping, so at least add it though it will be missing array1 data 
     map[arrayValue[key2]] = arrayValue; 
     map.push(arrayValue); 
    } 
    } 

    return map; 
} 

var mergedArrays = mergeObjectArrays(obj1, 'fruit', obj2, 'fruit_name'); 

Here's a working sample.

0

不是一般的解決方案,但足以讓你的情況:

var obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}] 
 
var obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}] 
 

 
var obj3 = obj2.map(o => Object.assign({}, o, {'sweetness': obj1.find(p => p.fruit === o.fruit_name).sweetness})) 
 

 
console.log(obj3)

+0

你甚至可以使用[對象擴展語法](https://github.com/tc39/proposal-object-rest-spread)來縮短代碼 –

+0

這一個內膽解決方案很漂亮,因爲我試圖使用嵌套for循環來解決問題。我在這裏問過尋找更優雅的解決方案,那就是它。 – DanFragoso

相關問題