最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to combine Lodash _.forEach() with _.groupBy - Stack Overflow

programmeradmin0浏览0评论

I have an object with arrays of objects. I'm trying to loop through these arrays with _.forEach() and then group each array with _.groupBy(). But the function is just returning the original data.

const testData = {
  "1": [
    { name: "john", job: "programmer" },
    { name: "jean", job: "dentist" },
    { name: "jo", job: "programmer" },
    { name: "jeff", job: "chef" },
    { name: "jock", job: "dentist" }
  ],
  "2": [
    { name: "julie", job: "doctor" },
    { name: "billy", job: "clerk" },
    { name: "carol", job: "doctor" },
    { name: "claire", job: "clerk" },
    { name: "cedric", job: "lawyer" }
  ]
};

const groupedTest = data => {
  return _.forEach( data, arraygroup => {
    _.groupBy( arraygroup, obj => obj.job );   
  } );
};


const result = groupedTest(testData)

console.log( result );
<script src=".js/4.17.11/lodash.js"></script>

I have an object with arrays of objects. I'm trying to loop through these arrays with _.forEach() and then group each array with _.groupBy(). But the function is just returning the original data.

const testData = {
  "1": [
    { name: "john", job: "programmer" },
    { name: "jean", job: "dentist" },
    { name: "jo", job: "programmer" },
    { name: "jeff", job: "chef" },
    { name: "jock", job: "dentist" }
  ],
  "2": [
    { name: "julie", job: "doctor" },
    { name: "billy", job: "clerk" },
    { name: "carol", job: "doctor" },
    { name: "claire", job: "clerk" },
    { name: "cedric", job: "lawyer" }
  ]
};

const groupedTest = data => {
  return _.forEach( data, arraygroup => {
    _.groupBy( arraygroup, obj => obj.job );   
  } );
};


const result = groupedTest(testData)

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

I'm looking to return a new object with the arrays grouped by job, but this function is just returning the original data. I can't figure out where I've gone wrong with the logic :-( Thanks very much for any help you can give me..

Share Improve this question edited May 24, 2019 at 3:43 Jack Bashford 44.1k11 gold badges55 silver badges82 bronze badges asked May 24, 2019 at 3:30 fergusfergus 2132 silver badges9 bronze badges 1
  • 1 What should the output be? – Jack Bashford Commented May 24, 2019 at 3:36
Add a ment  | 

3 Answers 3

Reset to default 3

_.forEach returns the original collection - use _.map and make sure you're returning everything.

const testData = {"1":[{name:"john",job:"programmer"},{name:"jean",job:"dentist"},{name:"jo",job:"programmer"},{name:"jeff",job:"chef"},{name:"jock",job:"dentist"}],"2":[{name:"julie",job:"doctor"},{name:"billy",job:"clerk"},{name:"carol",job:"doctor"},{name:"claire",job:"clerk"},{name:"cedric",job:"lawyer"}]};

const groupedTest = data => _.map(data, arraygroup => _.groupBy(arraygroup, obj => obj.job));

const result = groupedTest(testData)

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: auto; }
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.11/lodash.js"></script>

With lodash you could do _.values followed by _.map and then inside go with _.groupBy in order to get the grouping by job:

const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };

let result = _.map(_.values(data), arr => _.groupBy(arr, 'job'))

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

If you actually want to preserve the keys in the initial object then simply use _.mapValues with _.groupBy:

const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };

let result = _.mapValues(data, arr => _.groupBy(arr, 'job'))

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

Very similar and without the need of lodash you can do with ES6:

const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };

let result = Object.values(data).map(x => x.reduce((r, {name, job}) => {
  r[job] = [...(r[job] || []), {name, job}]
  return r
}, {}))

console.log(result)

Difference is that we achieve the group by via Array.reduce

Another option would be to consider the use of built in functions Object.entries() and Array.reduce() to achieve what you require:

const testData = {
  "1": [
    { name: "john", job: "programmer" },
    { name: "jean", job: "dentist" },
    { name: "jo", job: "programmer" },
    { name: "jeff", job: "chef" },
    { name: "jock", job: "dentist" }
  ],
  "2": [
    { name: "julie", job: "doctor" },
    { name: "billy", job: "clerk" },
    { name: "carol", job: "doctor" },
    { name: "claire", job: "clerk" },
    { name: "cedric", job: "lawyer" }
  ]
};


/*
Iterate key/value pairs of testData and reduce these to a new results object
where values are nested grouping object
*/
const results = Object.entries(testData).reduce((output, [key,array]) => {

  /* 
  Reduce array value to a group, where the grouping is based on the job key
  */
  const group = array.reduce((result, item) => {
    
    if( Array.isArray( result[ item.job ] )) {
    
      /*
      If item.job key present in result (corresponding group) then add item
      to the key's group value
      */
      result[ item.job ].push(item);
    }
    else {
    
      /*
      Otherwise, start a new group array for this yet unseen item.job key 
      */
      result[ item.job ] = [ item ];
    }
    return result;

  }, {});
  
  output[ key ] = group;
  return output;

}, {});



console.log(results)

The advantage of this approach is that it is independent of the loadash library

发布评论

评论列表(0)

  1. 暂无评论