1

I have 2 objects array as follows:

arr1 =  [ { 'v1': 'abcde',
    'pv_45': 13018, 
    'geolocation': '17.340291,76.842807'
   }]

arr2 =[{ 'v1':'abcde',
    'pv_50': 13010,    
    geolocation: '17.340291,76.842807'
    }]

I want to merge the above 2 array int0 single based on condition that 'v1' and 'geolocation' should be same as follows:

[{'v1':'abcde',
      'pv_45': 13018, 
      'pv_50': 13010,
      'geolocation': '17.340291,76.842807'}]

I used _.extend, but its not checking any condition blindly it will merge. Please share your ideas. Thanks in advance.

4
  • stackoverflow.com/questions/171251/… Commented Apr 22, 2015 at 10:50
  • can both arrays contain more than 1 element? if not it should be simple to code yourself, else it might be a bit harder Commented Apr 22, 2015 at 10:52
  • @ RemyNL sometimes it can..But not sure that both array have the same length.. Commented Apr 22, 2015 at 10:54
  • groupBy geolocation, and merge the resulting groups. Commented Apr 22, 2015 at 11:01

4 Answers 4

1

you can use underscore js union and uniq to do that.

var mergedArray = _.uniq(_.union(c1, c2), false, function(item, key, a){ return item; });
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks but i am getting the output..Its not merging.
what is the output you are getting?
[{'v1':'abcde', 'pv_45': 13018, 'geolocation': '17.340291,76.842807'}]
maybe try only var mergedArray = _.union(c1, c2); only.
1

Using pure JavaScript it could be done like this:

var arr1 =  [ { 'v1': 'abcde',
    'pv_45': 13018, 
    'geolocation': '17.340291,76.842807'
  }],
  arr2 =[{ 'v1':'abcde',
    'pv_50': 13010,    
    geolocation: '17.340291,76.842807'
  }],
  mergeOnV1Geo = function (arr1, arr2) {
    var mergeObj = {},
      merge = function (item) {
        var key = item.v1 + ',' + item.geolocation;
        // if this is the first object with this key
        // create a new object and copy v1, geolocation info
        if (!mergeObj[key]) {
          mergeObj[key] = {
            v1: item.v1,
            geolocation: item.geolocation
          };
        }
        // add other props
        Object.keys(item).forEach(function (prop) {
          if (!prop.match(/v1|geolocation/)) {
            mergeObj[key][prop] = item[prop];
          }
        });
      };
    arr1.forEach(merge);
    arr2.forEach(merge);

    // map back into an array
    return Object.keys(mergeObj).map(function (key) {
      return mergeObj[key];
    });

  };

mergeOnV1Geo(arr1, arr2);

4 Comments

Thanks for your valuable time. I have this logic code with me. But i need some efficient way to accomplish this.
I don't know if you can get much more efficient. This code make a single pass over each input array and then one more pass over the merged data to convert it back into an array.
@ Useless Code suppose consider that the array of different length. What would happen??
The length of the arrays doesn't matter. If they are different lengths the code would act exactly the same. merge is run once for each item in the input arrays and then mergeObj is converted to an array. Longer arrays would take more time to complete but that would happen with any method you use. Using Underscore, each Underscore method you use will make at least one pass over the data. You might be able to write it with less code using Underscore but it will probably be less efficient in terms of performance.
1

You could do the following:

var arr3 = [].concat.apply([], arr1, arr2);
var temp =_.groupBy(arr3, 'geolocation');
var result = Object.keys(_.groupBy(arr3, 'geolocation')).map(function(x)  {  return _.extend.apply(0, p[x]); })

if you prefer ES-6 arrow functions the result becomes

Object.keys(_.groupBy(arr3, 'geolocation')).map((x) => _.extend.apply(0, p[x]);)

Comments

0

ES6: Using spread operator and reduce.

arr1 =  [{ v1: 'abcde',
  pv_45: 13018, 
  geolocation: '17.340291,76.842807'
}]

arr2 =[{ v1:'abcde',
  pv_50: 13010,    
  geolocation: '17.340291,76.842807'
}]

// Keys to be grouped i.e whose values should be equal
groupableKeys = ['v1', 'geolocation'];

// Reducer that creates an Object with Key as the
// groupable key values value1::value2 and Value as
// the list of objects whose v1 and geolocation are same
groupableReducer = (a, b) => {
  const uniqKey = groupableKeys.map(key => b[key]).join("::");
  a[uniqKey] = [...(a[uniqKey] || []), b];
  return a;
}

// Merges two objects using the spread operator
mergableReducer = (a, b) => ({...a, ...b})

// Merge two arrays and start processing
groupableKeyObject = [...arr1, ...arr2].reduce(groupableReducer, {})

output = Object.keys(groupableKeyObject)
               .map(key => 
                   groupableKeyObject[key].reduce(mergableReducer, {})
                )

console.log(output);

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.