Как объединить Lodash _.forEach () с _.groupBy - PullRequest
4 голосов
/ 24 мая 2019

У меня есть объект с массивами объектов. Я пытаюсь перебрать эти массивы с помощью _.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 ]

3 голосов
/ 24 мая 2019

_.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 голос
/ 24 мая 2019

С 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

1 голос
/ 24 мая 2019

Другой вариант - рассмотреть возможность использования встроенных функций 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

...