2017-08-17 66 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

相关问题