2016-12-25 1 views
4

У меня есть ниже двух массивов:создать сгруппированный массив с использованием двух различных массивов

array1 = [{ 
    "type":"test", 
    "name":"name1"}, 
{ 
    "type":"dev", 
    "name":"name2"}] 

array2=[{ 
     "type":"test", 
     "name":"name3"}, 
     { 
     "type":"dev", 
     "name":"name4"}, 
     { 
     "type":"prod", 
     "name":"name5"}] 

Я хочу, чтобы сгруппировать два массива с «типа» и создать новый массив что-то вроде этого:

finalArray=[{ 
      "type":"test", 
      "info":[{ 
         "type":"test", 
         "name":"name1"}], 
        [{ 
         "type":"test", 
         "name":"name3" 
        }]}, 
      { 
       "type":"dev", 
       "info":[{ 
         "type":"dev", 
         "name":"name2"}], 
        [{ 
         "type":"dev", 
         "name":"name4"}]}, 
      { 
       "type":"prod", 
       "info":[], 
        [{ 
         "type":"prod", 
         "name":"name5"}] 
       }] 

Есть ли в любом случае, что я могу достичь этого, используя javascript, angularjs2, lodash, jquery. Я могу сгруппировать и создать новый объект, как указано в: using lodash .groupBy. how to add your own keys for grouped output?

Но только я всегда хочу, чтобы данные из второго массива были в индексе = 1 из «info», а сначала в индекс = 0. Если какой-либо из массива не имеет «типа», тогда массив «info» должен иметь пустые/нулевые значения.

ответ

1

Возможно получить результат, который вы хотите в javascript, или с помощью помощника, такого как lodash. Последнюю часть вашего вопроса трудно понять. Если в массиве нет «типа», как бы вы их группировали. Просьба предоставить более четкое объяснение или изменить ожидаемый ввод и вывод.

[Обновлено] Спасибо за ваше объяснение. Это решение, использующее простой javascript.

// get uniques type from two arrays 
const uniqueTypes = new Set(array1 
          .concat(array2) 
          .map(x => x.type)); 

// loop the types, find item in both array 
// group it 
let result = Array.from(uniqueTypes).reduce((acc, curr) => { 
    const item1 = array1.find(x => x.type === curr); 
    const item2 = array2.find(x => x.type === curr); 

    const info1 = item1 ? [item1] : []; 
    const info2 = item2 ? [item2] : []; 

    acc = acc.concat({ type: curr, info: [info1, info2] }); 

    return acc; 
}, []); 


console.log(result); 

jsbin здесь: https://jsbin.com/mobezogaso/edit?js,console

+0

Что касается вашего вопроса - "типа": "прод" является дзю st во втором массиве (array2), остальные типы находятся в обоих массивах - таким образом, в конечном массиве «информация» будет удерживаться ключ - один пустой массив (тип отсутствует в массиве 1) и один с ключами/значениями из array2 (если я правильно понимаю) :) – sinisake

+0

обновленная база на ваши объяснения. теперь ясно. – Chybie

+0

@Chybie - Спасибо за решение, которого я ожидаю. У меня есть еще одна проблема: как я могу динамически передавать «тип» в .map (x => x.type). Потому что я сохранил это в общем методе, чтобы я мог группировать разные ключи, передавая имя ключа в качестве параметра. – user3878988

1

Вот рабочий раствор :). Надеюсь, поможет!

var array1 = [ 
 
{ 
 
"type":"test", 
 
"name":"name1" 
 
}, 
 
{ 
 
"type":"dev", 
 
"name":"name2" 
 
} 
 
] 
 

 
var array2 = [ 
 
{ 
 
"type":"test", 
 
"name":"name3" 
 
}, 
 
{ 
 
"type":"dev", 
 
"name":"name4" 
 
}, 
 
{ 
 
"type":"prod", 
 
"name":"name5" 
 
} 
 
] 
 

 

 
var newArray = array1.concat(array2); 
 
var arr1 = []; 
 
var arr2 = []; 
 
var arr3 = []; 
 
var arrTypes = []; 
 
var finalArray = []; 
 
var someArray = []; 
 

 
for(var i in newArray) 
 
{ 
 
if (arrTypes.indexOf(newArray[i].type) === -1){ 
 
    arrTypes.push(newArray[i].type); 
 
} 
 

 
if(newArray[i].type === "test"){ 
 
    arr1.push(newArray[i]); 
 
} 
 
else if(newArray[i].type === "dev"){ 
 
    arr2.push(newArray[i]); 
 
} 
 
else if(newArray[i].type === "prod"){ 
 
    arr3.push(newArray[i]); 
 
} 
 
} 
 
someArray.push(arr1); 
 
someArray.push(arr2); 
 
someArray.push(arr3); 
 

 
for(var j = 0; j < someArray.length; j++){ 
 
\t finalArray.push({ 
 
\t \t "type": arrTypes[j], 
 
\t \t "info": someArray[j] 
 
\t }); 
 
} 
 
console.log(finalArray);

2

использование _.mapValues для перебора значений объекта с ключом доступа к

var res = _.chain(array1) 
    .concat(array2) 
    .groupBy('type') 
    .mapValues(function(val, key) { 
     return { 
      type: key, 
      info: val 
     }; 
    }) 
    .values() 
    .value(); 
0

и короткий (нечитаемый?) ES6 решение:

  1. Concat массивов
  2. Сократить массив в объект Map, с типом как ключевыми
  3. Получить записи итератора - ключ (типа) - значение (массив объектов)
  4. Используйте распространение для преобразования входного итератора в массив
  5. Array#Map массив записей к типу/информации объекты

const array1 = [{"type":"test","name":"name1"},{"type":"dev","name":"name2"}]; 
 
const array2=[{"type":"test","name":"name3"},{"type":"dev","name":"name4"},{"type":"prod","name":"name5"}]; 
 

 
const result = [...array1.concat(array2).reduce((r, o) => { 
 
    r.has(o.type) ? r.get(o.type).push(o) : r.set(o.type, [o]); 
 
    return r; 
 
    }, new Map).entries()] 
 
    .map(([type, info]) => ({ 
 
    type, info 
 
    })); 
 

 
console.log(result);

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