2016-09-01 42 views
2

у меня есть два массива объектов:Как объединить два словаря в JavaScript

Array1:

var myArr1 = []; 
myArr1["1"]={any:1,some:1}; 
myArr1["2"]={any:2,some:2}; 
myArr1["3"]={any:3,some:3}; 

array2:

var myArr2 = []; 
myArr2["1"]={other:1};  
myArr2["2"]={other:2}; 

И я хочу, чтобы они были объединены с помощью их ключей в новый атрибут, поэтому результатом будет:

[ 
    {any:1,some:1,myNewAttribute:{other:1}}, 
    {any:2,some:2,myNewAttribute:{other:2}}, 
    {any:3,some:3,myNewAttribute:{other:3}} 
] 

Я попытался добиться этого с помощью lodash's _.merge(), но я потерпел неудачу с треском. _.merge только добавляет второй массив после первого, но не соответствует их ключам/идентификаторам.

+1

Является ли это псевдо-код? Javascript имеет объекты, а не dicts. Что именно не сработало для вас с '_.merge'? –

+1

Глядя на ваш желаемый результат, первый элемент имеет свойство 'some', но не второе или третье? Это действительно то, что вы хотите, или вы хотите использовать свойство 'some' для всех элементов в результате? –

+0

Я редактировал вопрос. Я знаю, как вручную комбинировать их с 'for'-loop, но я хотел сохранить его элегантным с lodash .. –

ответ

3

Вы можете сопоставить второй массив с новым свойством и слить его позже.

С lodash

var data1 = [{ any: 1, some: 1 }, { any: 2, some: 2 }, { any: 3, some: 3 }], 
 
    data2 = [{ other: 1 }, { other: 2 }, { other: 3 }]; 
 

 
console.log(_.merge(data1, _.map(data2, x => ({ myNewAttribute: x }))));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

С ES6 без lodash

var data1 = [{ any: 1, some: 1 }, { any: 2, some: 2 }, { any: 3, some: 3 }], 
 
    data2 = [{ other: 1 }, { other: 2 }, { other: 3 }]; 
 

 
console.log(data1.map((a, i) => Object.assign({}, a, { myNewAttribute: data2[i] })));

0

Вы можете сделать так:

var first = [{any:1,some:1},{any:2,some:2},{any:3,some:3}]; 
var second = [{other:1},{other:2},{other:3}]; 

for(var i = 0; i < first.length; i++){ 
    if(first[i] && second[i]){ 
     first[i]['mycustomitem'] = second[i]; 
    } 
} 

console.log(first); 
1

Вам не нужно lodash:

myArr1.map((e1, idx) => Object.assign({}, e1, {myNewAttribute: myArr2[idx]})) 

Вы можете получить фантазии и написать небольшую функцию, называемую map2, которая принимает два массива, и вызывает функцию обратного вызова с двумя элементами:

function map2(a1, a2, fn) { 
    return a1.map((elt, idx) => fn(elt, a2[idx]); 
} 

Теперь вы можете записать решение в виде

map2(myArr1, myArr2, (e1, e2) => Object.assign({}, e1, {myNewAttribute: e2})) 

С точки зрения дизайна программы, то, что мы здесь делаем, - «разделение проблем». Первой проблемой является абстрактная операция циклизации над двумя массивами параллельно и делает что-то с каждой парой элементов. Это то, что представлено map2. Вторая проблема заключается в том, как вы хотите объединить элементы. Это то, что представлено функцией, которую мы переходим на map2. Это можно было бы сделать более ясным и несколько самодокументируемыми, написав его отдельно:

function combineObjects(e1, e2) { 
    return Object.assign({}, e1, {myNewAttribute: e2}); 
} 

map2(myArr1, myArr2, combineObjects); 

Конечно, в реальном мире, вы хотите, чтобы обрабатывать случай, когда два массива были разной длины, проходят индекс для обратного вызова в качестве третьего параметра для использования, если необходимо, поддерживайте третий параметр thisArg, аналогичный параметру map и т. д.

-1

Попробуйте эту функцию:

function mergeDictionary(_dctn1,_dctn2) 
 
{ 
 
    var newDict = []; 
 
    for(var i in _dctn1) 
 
    { 
 
     newDict[i] = _dctn1[i]; 
 
    } 
 
    for(var j in _dctn2) 
 
    { 
 
     if(newDict[j] == undefined) 
 
     { 
 
      newDict[j] = _dctn2[j]; 
 
     } 
 
     else 
 
     { 
 
      for(var k in _dctn2[j]) 
 
      { 
 
       newDict[j][k] = _dctn2[j][k]; 
 
      } 
 
     } 
 
    
 
    } 
 
    
 
    return newDict; 
 
} 
 

 

 
var myArr1 = []; 
 
myArr1["1"]={any:1,some:1}; 
 
myArr1["2"]={any:2,some:2}; 
 
myArr1["3"]={any:3,some:3}; 
 

 
var myArr2 = []; 
 
myArr2["1"]={other:1};  
 
myArr2["2"]={other:2}; 
 

 
console.log(mergeDictionary(myArr1, myArr2));

+0

Почему вы используете термин «словарь», когда у JS нет даже словарей? Объекты, о которых идет речь, представляют собой массивы. Зачем вам писать цикл для копирования массива, когда вы могли бы написать 'newDict = _dctn1.slice();'? –

+1

Надеюсь, вы не против, но я сделал ваш код исполняемым фрагментом. Если вы запустите его, вы заметите, что это не похоже на то, что задает вопрос. – JJJ

+0

На самом деле это должен быть объект вместо массива – spankajd

0

Для того, чтобы доказать, что я сделал комментарий 30 минут назад - How to merge two dictionaries in javascript - есть возможный reduce подход ...

... в первую очередь представлен как lodash на основе ...

var 
 
    myArr1 = [ 
 
     {any: 1, some: 1}, 
 
     {any: 2, some: 2}, 
 
     {any: 3, some: 3} 
 
    ], 
 
    myArr2 = [ 
 
     {other: 1}, 
 
     {other: 2} 
 
    ], 
 

 
    mergedObjectList = _.reduce(myArr1, function (collector, item_1, idx) { 
 
     var 
 
      item_2 = collector[idx], 
 
      merger = _.assign({}, item_1, item_2); 
 

 
     // or whatever one wants to do to `merger` with `myNewAttribute` 
 

 
     collector[idx] = merger; 
 

 
     return collector; 
 

 
    }, _.clone(myArr2)); 
 

 

 
console.log("myArr1 : ", myArr1); 
 
console.log("myArr2 : ", myArr2); 
 
console.log("mergedObjectList : ", mergedObjectList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

... а во-вторых, как языка ядра только пример на основе ...

var 
 
    myArr1 = [ 
 
     {any: 1, some: 1}, 
 
     {any: 2, some: 2}, 
 
     {any: 3, some: 3} 
 
    ], 
 
    myArr2 = [ 
 
     {other: 1}, 
 
     {other: 2} 
 
    ], 
 

 
    mergedObjectList = myArr1.reduce(function (collector, item_1, idx) { 
 
     var 
 
      item_2 = collector[idx], 
 
      merger = Object.assign({}, item_1, item_2); 
 

 
     // or whatever one wants to do to `merger` with `myNewAttribute` 
 

 
     collector[idx] = merger; 
 

 
     return collector; 
 

 
    }, Array.from(myArr2)); 
 

 

 
console.log("myArr1 : ", myArr1); 
 
console.log("myArr2 : ", myArr2); 
 
console.log("mergedObjectList : ", mergedObjectList);

+0

Есть ли причина, по которой вы отступаете от кодовых тегов? –

+1

@NinaScholz - спасибо за подсказку, это произошло случайно и уже исправлено. –

Смежные вопросы