thawley thawley - 5 months ago 36
Javascript Question

Use lodash to group array into tree "children" structure

Using lodash, I need to convert the following array:

[{
text: 'apple',
type: 'fruit'
}, {
text: 'pear',
type: 'fruit',
}, {
text: 'potato',
type: 'vegetable'
}, {
text: 'water',
type: 'beverage'
}]


Into the following format:

[{
text: 'fruit',
children: [{
text: 'apple',
type: 'fruit'
}, {
text: 'pear',
type: 'fruit'
}]
}, {
text: 'vegetable',
children: [{
text: 'potato',
type: 'vegetable'
}]
}, {
text: 'beverage',
children: [{
text: 'water',
type: 'beverage'
}]
}]


I've attempted to chain lodash methods like
groupBy
and
transform
, but am having a hard time getting to the resulting format I require.

Here's a skeleton of what direction I was heading:

_(arr).groupBy('type').transform(function(result, obj, type) {
return result.push({
name: type,
children: obj
});
}).value();


The issue I'm running into is
groupBy
turns my array into an Object, so I can no longer simply
push
onto an Array. Being relatively knew with lodash (around 4 or 5 months of experience), I wanted to see if others have already tackled such a requirement.

Answer

Use _.reduce() instead of transform, because it lets you state the end product format:

var arr = [{
  text: 'apple',
  type: 'fruit'
}, {
  text: 'pear',
  type: 'fruit',
}, {
  text: 'potato',
  type: 'vegetable'
}, {
  text: 'water',
  type: 'beverage'
}];

var results = _(arr)
  .groupBy('type')
  .reduce(function(array, children, key) {
    array.push({
      text: key,
      children: children
    });

    return array;
  }, []);

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