admin管理员组

文章数量:1410682

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

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

Share Improve this question edited May 24, 2017 at 18:15 mspasiuk asked May 24, 2017 at 17:26 mspasiukmspasiuk 6322 gold badges9 silver badges23 bronze badges 3
  • 5 What do you expect the end result to look like? – Whymarrh Commented May 24, 2017 at 17:28
  • Possible duplicate of How to get distinct values from an array of objects in JavaScript? – Josh Knack Commented May 24, 2017 at 17:34
  • @Whymarrh I edited the question. Thanks! – mspasiuk Commented May 24, 2017 at 18:16
Add a ment  | 

4 Answers 4

Reset to default 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
         }
      ]
   }
]

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"]
    }
]

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/lodash/4.17.4/lodash.min.js"></script>

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

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);

本文标签: javascriptlodash get an array of element grouped by a keyStack Overflow