如何将Lodash _.forEach()与_.groupBy组合

时间:2019-05-24 03:30:05

标签: javascript arrays object ecmascript-6 lodash

我有一个带有对象数组的对象。我试图通过_.forEach()遍历这些数组,然后使用_.groupBy()对每个数组进行分组。但是该函数只是返回原始数据。

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.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

我希望返回一个具有按作业分组的数组的新对象,但是此功能只是返回原始数据。我不知道我在逻辑上出了什么问题:-(非常感谢您能为我提供的任何帮助。

3 个答案:

答案 0 :(得分:3)

_.forEach返回原始集合-使用_.map并确保您返回的所有内容。

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.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

答案 1 :(得分:1)

另一种选择是考虑使用内置函数Object.entries()Array.reduce()来达到您的要求:

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)

这种方法的优点是它独立于loadash库

答案 2 :(得分:1)

使用lodash可以先进行_.values,然后进行_.map,然后在内部进行_.groupBy,以便按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.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

如果您实际上想将密钥保留在初始对象中,则只需将_.mapValues_.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.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

非常相似并且不需要lodash,您可以使用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)

不同之处在于,我们通过Array.reduce