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.

4 Answers 4

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();
Sign up to request clarification or add additional context in comments.

Comments

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

3 Comments

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) :)
@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.
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])); `
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);

Comments

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.