Страницы

Поиск по вопросам

суббота, 4 января 2020 г.

Объединить два массива с объединением полей объектов

#javascript #массивы


Подскажите плиз как объединить несколько массивов в один.
Допустим у меня есть массивы следующего вида

var first = [
    { id: 1, name: 'first' },
    { id: 2, name: 'second' },
    { id: 3, name: 'third' }
]

var second = [
    { id: 2, filed: 'foo2' },
    { id: 3, field: 'foo3' },
    { id: 4, field: 'foo4' }
]

var third = [
    { id: 2, data: 'some2' },
    { id: 4, data: 'some4' },
    { id: 6, data: 'some6' }
]


Я хотел бы объединить их чтобы получить такой результат:

var result = [
    { id: 1, name: 'first',   field: undefined, data: undefined },
    { id: 2, name: 'second',  field: 'foo2',    data: 'some2' },
    { id: 3, name: 'third',   field: 'foo3',    data: undefined },
    { id: 4, name: undefined, field: 'foo4',    data: 'some4' },
    { id: 5, name: undefined, field: undefined, data: undefined },
    { id: 6, name: undefined, field: undefined, data: 'some6' }
]


Как это можно сделать? Заранее спасибо
    


Ответы

Ответ 1



Если объединение идет по свойству id, то можно использовать следующий код: function merge() { var hash = {}; // временный хэш объектов по свойству id for (var l = 0; l < arguments.length; l++) { var arr = arguments[l]; if (!arr.length) continue; for (var i = 0; i < arr.length; i++) { var el = arr[i]; if (!('id' in el)) continue; var id = el.id; if (!hash[id]) hash[id] = {}; for (var key in el) { if (el.hasOwnProperty(key)) hash[id][key] = el[key]; } } } var result = []; for (var id in hash) { if (hash.hasOwnProperty(id)) result.push(hash[id]); } return result; } var result = merge(first, second, third);

Ответ 2



function merge(){ var result = []; Array.prototype.forEach.call(arguments, function(arr){ // Проходимся по переданным агрументам, функция принимает неограниченное количество аргументов if(Array.isArray(arr)){ for(e in arr){ // Проходимся по всем e = arr[e]; // переданным объектам var tmp = {}, isAdd = true; result.some(function(i){ if(i.id == e.id){ tmp = i; // Если в массиве уже был объект с данным id, то берём его isAdd = false; // и запрещаем добавлять его в результат return true; } }); for(prop in e){ tmp[prop] = e[prop]; // Изменяем/добавляем свойства из переданного объекта } if(isAdd) result.push(tmp); } } }); return result; } var first = [ { id: 1, name: 'first' }, { id: 2, name: 'second' }, { id: 3, name: 'third' } ]; var second = [ { id: 2, filed: 'foo2' }, { id: 3, field: 'foo3' }, { id: 4, field: 'foo4' } ]; var third = [ { id: 2, data: 'some2' }, { id: 4, data: 'some4' }, { id: 6, data: 'some6' } ]; var res = merge(first, second, third); console.info(res); /* => [ { "id": 1, "name": "first" }, { "id": 2, "name": "second", "filed": "foo2", "data": "some2" }, { "id": 3, "name": "third", "field": "foo3" }, { "id": 4, "field": "foo4", "data": "some4" }, { "id": 6, "data": "some6" }, length: 5 ] */

Ответ 3



Если вы планируете работать с коллекциями, объединять их, сортировать и производить прочие подобные операции, то я бы порекомендовал вам использовать для этого специальную библиотеку: Lodash или Underscore

Ответ 4



Для выполнения запросов удобно работать с LINQ.js. // Приводим массивы к удобному виду — словарю "индентификатор-значение" var names = Enumerable.From(first) .ToObject("$.id", "$.name"); var fields = Enumerable.From(second).ToObject("$.id", "$.field"); var datas = Enumerable.From(third) .ToObject("$.id", "$.data"); // Получаем общий список ключей — объединение списков ключей из трёх словарей выше var keys = Enumerable.From(Object.keys(names)) .Union(Object.keys(fields)) .Union(Object.keys(datas)); // Объединяем в общее перечисление var joined = keys.Select(function (id) { return { id: id, name: names[id], field: fields[id], data: datas[id] }; }); // Преобразуем перечисление к стандартному массиву console.log(joined.ToArray()); var first = [ { id: 1, name: 'first' }, { id: 2, name: 'second' }, { id: 3, name: 'third' } ]; var second = [ { id: 2, filed: 'foo2' }, { id: 3, field: 'foo3' }, { id: 4, field: 'foo4' } ]; var third = [ { id: 2, data: 'some2' }, { id: 4, data: 'some4' }, { id: 6, data: 'some6' } ]; var names = Enumerable.From(first).ToObject("$.id", "$.name"); var fields = Enumerable.From(second).ToObject("$.id", "$.field"); var datas = Enumerable.From(third).ToObject("$.id", "$.data"); var keys = Enumerable.From(Object.keys(names)) .Union(Object.keys(fields)) .Union(Object.keys(datas)); var joined = keys.Select(function (id) { return { id: id, name: names[id], field: fields[id], data: datas[id] }; }); document.write(joined.ToJSON());

Ответ 5



function smartMerge(mainProp, arrays) { /* Более универсальная версия, но требуется оптимизация mainProp - общее свойство для всех элементов, всех массивов: число arrays = массив массивов ( простите за тавтологию ) */ var mergedArray = []; // конечный массив for(var arrayIndex in arrays) { var array = arrays[arrayIndex]; for( var elementIndex in array) { var element = array[elementIndex]; if (!mergedArray[element[mainProp]]) mergedArray[element[mainProp]]={}; for( var prop in element) { mergedArray[element[mainProp]][prop] = element[prop]; } } } return mergedArray.filter(function (el) { return el;}); } // используем var arr = smartMerge('id', [first, second, third]); Живой пример( ответ в консоли )

Ответ 6



Все можно сделать намного легче с помощью concat var result = first.concat(second, third);

Комментариев нет:

Отправить комментарий