1

I have a JSON array returned by an API call

[{
    "id": 1,
    "name": "aa",
    "zone": 1

}, {
    "id": 2,
    "name": "bb",
    "zone": 1

}, {
    "id": 3,
    "name": "cc",
    "zone": 2

}, {
    "id": 3,
    "name": "dd",
    "zone": 2
}
]

By using lodash I did _.groupBy(myData,'zone') and the result was an Object containing 2 arrays, each one for a different zone. But what I need to achieve, in an object containing an array of zones and for each zone an array of associated names.

Desired result:

[
   {
      "zone": "1",
      "items": [
         {
            "id": 1,
            "name": "aa",
            "zone": 1
         },
         {
            "id": 2,
            "name": "bb",
            "zone": 1
         }
      ]
   },
   {
      "zone": "2",
      "items": [
         {
            "id": 3,
            "name": "cc",
            "zone": 2
         },
         {
            "id": 3,
            "name": "dd",
            "zone": 2
         }
      ]
   }
]

Is possible to transform the original array into the one I need using lodash? Later on my Angular template I want to do an *ngFor='let zone of zones' or something similar

mspasiuk
  • 602
  • 1
  • 7
  • 23

4 Answers4

7

Assuming you did this :

result = _.groupBy(myData,'zone')

just add this after the lodash function:

result = Object.keys(result).map(key => ({ zone: key, items: result[key] }));

And you'll get this :

 [
   {
      "zone": "1",
      "items": [
         {
            "id": 1,
            "name": "aa",
            "zone": 1
         },
         {
            "id": 2,
            "name": "bb",
            "zone": 1
         }
      ]
   },
   {
      "zone": "2",
      "items": [
         {
            "id": 3,
            "name": "cc",
            "zone": 2
         },
         {
            "id": 3,
            "name": "dd",
            "zone": 2
         }
      ]
   }
]
SeleM
  • 9,310
  • 5
  • 32
  • 51
1

You can do:

let zones = _.chain(_.groupBy(myData, 'zone')).map(function (val, key) {
    return {
        zone: key,
        names: _.map(val, "name") // Assuming you only need names. You can have the whole object too if needed
    };
}).value();

This will produce:

[
    {
        "zone": "1",
        "names": ["aa", "bb"]
    },
    {
        "zone": "2",
        "names": ["cc", "dd"]
    }
]
Saravana
  • 37,852
  • 18
  • 100
  • 108
1

If you are looking to create a JSON object with some keys with zone values and the corresponding names as an array assigned to that key, you can use reduce function of lodash. Simply do:

_.reduce(myData, function(result, value, key) {
    (result[value.zone] || (result[value.zone] = [])).push(value.name);
    return result;
  }, {});

The code will produce:

{"1":["aa","bb"],"2":["cc","dd"]}

var myData = [{
  "id": 1,
  "name": "aa",
  "zone": 1

}, {
  "id": 2,
  "name": "bb",
  "zone": 1

}, {
  "id": 3,
  "name": "cc",
  "zone": 2

}, {
  "id": 3,
  "name": "dd",
  "zone": 2
}];

console.log(JSON.stringify(
  _.reduce(myData, function(result, value, key) {
    (result[value.zone] || (result[value.zone] = [])).push(value.name);
    return result;
  }, {})
));
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

Here you can find the lodash documentaion for reduce: https://lodash.com/docs/4.17.4#reduce

Sina Masnadi
  • 1,516
  • 17
  • 28
0

Below is my implementation of what you want, although without Lodash (at least what I think it is you want. The result is an array of arrays, each inner array containing each original object of a particular zone).

let originalArray = [{
    "id": 1,
    "name": "aa",
    "zone": 1

}, {
    "id": 2,
    "name": "bb",
    "zone": 1

}, {
    "id": 3,
    "name": "cc",
    "zone": 2

}, {
    "id": 3,
    "name": "dd",
    "zone": 2
}]

let transitionObject = {};

for (let i = 0; i < originalArray.length; i++) {
  let currentObject = originalArray[i];
  transitionObject[currentObject.zone] = transitionObject[currentObject.zone] || { names: []};
  transitionObject[currentObject.zone].names.push(currentObject.name);
}

console.log(transitionObject);
Robert Taussig
  • 581
  • 2
  • 11