4

I have below two arrays:

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

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

I want to group two arrays with "type" and create a new array something like this:

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"}]
               }]

Is there anyway that I can achieve this using javascript, angularjs2, lodash, jquery. I am able to group and create new object as mentioned in using lodash .groupBy. how to add your own keys for grouped output?

But only thing is always I want to push the data from second array in index=1 of "info" and first one to index=0. If any of the array does not have a "type" then the "info" array should have empty/null values.

Community
  • 1
  • 1
user3878988
  • 761
  • 3
  • 8
  • 20

4 Answers4

2

use _.mapValues to iterate object values with key accessing

var res =  _.chain(array1)
    .concat(array2)
    .groupBy('type')
    .mapValues(function(val, key) {
        return {
            type: key,
            info: val
        };
    })
    .values()
    .value();
stasovlas
  • 7,136
  • 2
  • 28
  • 29
1

It's possible to achieve the result you want in javascript, or using helper like lodash. The last part of your question is hard to understand. If an array doesn't have "type", how would you group them. Please provide clearer explanation or modify your expected input and output.

[Updated] Thanks for your explanation. This is the solution using plain 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 here: https://jsbin.com/mobezogaso/edit?js,console

Jecfish
  • 4,026
  • 1
  • 18
  • 16
  • Regarding your question - "type":"prod" is just in second array (array2), the rest of the types are in both arays - thus, in final array 'info' key will hold - one empty array (type not present in array1), and one with keys/values from array2 (if i understand correctly) :) – sinisake Dec 25 '16 at 01:15
  • @Chybie - Thanks for the solution that I am expecting. I have one more issue that how can I pass 'type' dynamically in .map(x => x.type). Because I kept this in a common method so that I can group different keys by passing the key name as a parameter. – user3878988 Dec 27 '16 at 17:39
  • the easiest way, you don't even need a method, u need a variable to store the grouping key. e.g. ` const GROUP_KEY = 'type'; const uniqueTypes = new Set(array1 .concat(array2) .map(x => x[GROUP_KEY])); ` – Jecfish Dec 28 '16 at 13:56
1

Here's a working solution :). Hope it helps!

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++){
 finalArray.push({
  "type": arrTypes[j],
  "info": someArray[j]
 });
}
console.log(finalArray);
HenryDev
  • 4,685
  • 5
  • 27
  • 64
0

And a short (unreadable?) ES6 solution:

  1. Concat the arrays
  2. Reduce the array into a Map object, with the type as the key
  3. Get the entries iterator - key (type) - value (array of objects)
  4. Use spread to convert the entry iterator to an array
  5. Array#Map the array of entries to the type/info objects

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);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209