0

I want to aggregate array of object into single object with each object having distinct value. But My code is not giving me desired output. Can someone please help me?

My Input : 
    [{
        "obj1" : "value1",
        "obj2" : ["abc", "def"],
        "obj3" : ["ghi"],
        "obj4" : "value4",
    },
    {
        "obj1" : "value2",
        "obj2" : ["abc", "mno"],
        "obj3" : ["klm"],
        "obj4" : "value4",
    }]


Output I want:
{
    "obj1" : ["value1","value2"]
    "obj2" : ["abc", "def","mno"],
    "obj3" : ["ghi","klm"],
    "obj4" : ["value4"]
}

My Code:
const result = filterData.reduce((a,c) => 
  (Object.keys(c).map(k => a[k] = [...a[k] || [], c[k]]), a), {})

2 Answers 2

4

You can create a single object from an array of objects using array#reduce. You can get distinct value using Set.

const data = [{ "obj1" : "value1", "obj2" : ["abc", "def"], "obj3" : ["ghi"], "obj4" : "value4", }, { "obj1" : "value2", "obj2" : ["abc", "mno"], "obj3" : ["klm"], "obj4" : "value4", }],
      result = data.reduce((r,o) => {
        Object.keys(o).forEach(k => {
          r[k] = [...new Set((r[k] || []).concat(o[k]))];
        });
        return r;
      },{});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

3 Comments

Why do we need r[k] = r[k] || []; line? To check if the key exists?
It was initializing the array for the new key and the old key, it was not doing anything. I have updated the code
Great,it is much easier now to understand.
2

Here I use some helpers from lodash to solve your problem.

const input = [{
        "obj1" : "value1",
        "obj2" : ["abc", "def"],
        "obj3" : ["ghi"],
        "obj4" : "value4",
    },
    {
        "obj1" : "value2",
        "obj2" : ["abc", "mno"],
        "obj3" : ["klm"],
        "obj4" : "value4",
    }]
    
function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return _.union(objValue, srcValue);
  }
}
    
const output = input.reduce((acc, cur) => {
  const modifiedCur = _.mapValues(cur, function(o) { return typeof o === 'string' ? [o]: o; }); 
  acc = _.mergeWith(acc, modifiedCur, customizer);
  return acc
},{})    
    
console.log(output)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

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.