Lodash: merge an array of objects

In lodash, I want to convert an array of objects into a single object containing an array of each property.

I have an array of objects:

var students = [{
    name: 'A',
    idNo: 1,
    marks: {
        math: 98,
        sci: 97,
        eng: 89
    }
}, {
    name: 'B',
    idNo: 2,
    marks: {
        math: 88,
        sci: 87,
        eng: 79
    }
}, {
    name: 'C',
    idNo: 3,
    marks: {
        math: 87,
        sci: 98,
        eng: 91
    }
}]

I want to merge / modify them as follows:

{
    name: [A, B, C],
    idNo: [1, 2, 3],
    marks: [{
            math: 98,
            sci: 97,
            eng: 89
        }, {

            math: 88,
            sci: 87,
            eng: 79            
    }, {
            math: 87,
            sci: 98,
            eng: 91
        }
    }]
}

I want this to be done exclusively with the built-in lodash or js functions without any loops.

Edit: I have already implemented the solution proposed by Nenad. I want a utility function in lodash.

+4
source share
6 answers

You can use lodash mapValues :

var result = _.mapValues(students[0], (value, key) => _.map(students, key));

mapValues , , . students[0], , mapValues, :

{
    name: ....,
    idNo: ....,
    marks: ....
}

, mapValues . mapValues . , student ( map ).

var students = [{
    name: 'A',
    idNo: 1,
    marks: {
        math: 98,
        sci: 97,
        eng: 89
    }
}, {
    name: 'B',
    idNo: 2,
    marks: {
        math: 88,
        sci: 87,
        eng: 79
    }
}, {
    name: 'C',
    idNo: 3,
    marks: {
        math: 87,
        sci: 98,
        eng: 91
    }
}]


var result = _.mapValues(students[0], (value, key) => _.map(students, key));

document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

<p>
  <pre id="result"></pre>
</p>
Hide result
+4

reduce() forEach() .

var students = [{"name":"A","idNo":1,"marks":{"math":98,"sci":97,"eng":89}},{"name":"B","idNo":2,"marks":{"math":88,"sci":87,"eng":79}},{"name":"C","idNo":3,"marks":{"math":87,"sci":98,"eng":91}}];

var result = students.reduce(function(r, e) {
  Object.keys(e).forEach(function(k) {
    if (!r[k]) {
      r[k] = [];
    }
    r[k].push(e[k])
  })
  return r;
}, {})

console.log(result)
Hide result
+1

, _.mergeWith() :

const students = [{"name":"A","idNo":1,"marks":{"math":98,"sci":97,"eng":89}},{"name":"B","idNo":2,"marks":{"math":88,"sci":87,"eng":79}},{"name":"C","idNo":3,"marks":{"math":87,"sci":98,"eng":91}}];

const result = _.mergeWith({}, ...students, (objValue, srcValue) => 
  (objValue || []).concat(srcValue));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
Hide result

_.spread():

var students = [{"name":"A","idNo":1,"marks":{"math":98,"sci":97,"eng":89}},{"name":"B","idNo":2,"marks":{"math":88,"sci":87,"eng":79}},{"name":"C","idNo":3,"marks":{"math":87,"sci":98,"eng":91}}];
                                          
var result = _.spread(_.mergeWith)([{}].concat(students, function(objValue, srcValue){
  return (objValue || []).concat(srcValue);
}));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
Hide result
+1
source

You can do this with one shortcut;

var students = [{
    name: 'A',
    idNo: 1,
    marks: {
        math: 98,
        sci: 97,
        eng: 89
    }
}, {
    name: 'B',
    idNo: 2,
    marks: {
        math: 88,
        sci: 87,
        eng: 79
    }
}, {
    name: 'C',
    idNo: 3,
    marks: {
        math: 87,
        sci: 98,
        eng: 91
    }
}],
     result = students.reduce((p,c) => (p.name.push(c.name), p.idNo.push(c.idNo), p.marks.push(c.marks), p), {name:[], idNo:[], marks:[]});
console.log(result);
Run codeHide result
0
source

Another example of lodash with _.mergeWith

var students = [{ name: 'A', idNo: 1, marks: { math: 98, sci: 97, eng: 89 } }, { name: 'B', idNo: 2, marks: { math: 88, sci: 87, eng: 79 } }, { name: 'C', idNo: 3, marks: { math: 87, sci: 98, eng: 91 } }],
    result = {};

    _.forEach(students, v => _.mergeWith(result, v, (o, s) => !_.isArray(o) ? [s] : o.concat(s)));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Run codeHide result
0
source

Another example of lodash with . reduce (collection, [iteratee = .identity], [battery]) .

  • collection (Array|Object): collection for iteration.
  • [iteratee=_.identity] (Function): function called for each iteration.
  • [accumulator] (*): initial value.

the code:

var students = [{name: 'A', idNo: 1, marks: { math: 98, sci: 97, eng: 89}}, {name: 'B', idNo: 2, marks: { math:88,  sci: 87,  eng: 79}}, {name: 'C', idNo: 3, marks: { math: 87, sci: 98, eng: 91}}],
    obj = _.reduce(students, function(o, item) {
      o.name.push(item.name);
      o.idNo.push(item.idNo);
      o.marks.push(item.marks);
      return o;
    }, {name: [], idNo: [], marks: []});

console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Run codeHide result
0
source

Source: https://habr.com/ru/post/1657601/


All Articles