JavaScript group objects

2019-08-15 12:22发布

问题:

I have been looking for a few days now and I haven't found the answer to this specific problem. I'm receiving a javascript object array from an endpoint in my API. I need to group the objects together based on the Type.

example hard-coded array of objects:

$scope.content = {
    things: [
        {
            thing: 'one',
            thingType: 'load'
        },
        {
            thing: 'two',
            thingType: 'export'
        },
        {
            thing: 'three',
            thingType: 'export'
        }
    ]
}
var typeArr = [];
for (var key in $scope.content.things) {

     typeArr[key] = $scope.content.things[key].thingType;
}
typeArr = _.uniq(typeArr);

typeArr is now going to be [load, export] What I need to happen next is to compare all the objects in things[ ] such that

 if(typeArr[key] === things[i].thingType) 

would push that object like so:

typeArr = [
    load: {
        thing: 'one',
        thingType: 'load'
    },
    export: [{
        thing: 'two',
        thingType: 'export'
    },
    {
        thing: 'three',
        thingType: 'export'
     }

    ]
]

in other words, I need the objects to remain whole, and I need to categorize them, and nest them according to a shared type. I have seriously been stuck on this all week. Any insight would be greatly appreciated.

回答1:

Try this

   
var content = {
    things: [
        {
            thing: 'one',
            thingType: 'load'
        },
        {
            thing: 'two',
            thingType: 'export'
        },
        {
            thing: 'three',
            thingType: 'export'
        }
    ]
}
var typeArr = {};
content.things.forEach(function(item){
    typeArr[item.thingType] = typeArr[item.thingType]||[];
    typeArr[item.thingType].push(item);
});

document.body.innerHTML = JSON.stringify(typeArr);



回答2:

Would something like this be acceptable?

var things = [
    {
        thing: 'one',
        thingType: 'load'
    },
    {
        thing: 'two',
        thingType: 'export'
    },
    {
        thing: 'three',
        thingType: 'export'
    }
];

var types = {};

for (i in things) {
  var thing = things[i];
  if (typeof types[thing.thingType] === "undefined") {
    types[thing.thingType] = [];
  }
  types[thing.thingType].push(thing);
}

console.log(types);

The resulting types object would look like

{
    load: [{
        thing: 'one',
        thingType: 'load'
    }],
    export: [{
        thing: 'two',
        thingType: 'export'
    },
    {
        thing: 'three',
        thingType: 'export'
     }]
}

That is, each type is always an array even if it just contains one item (in your example it was just an object). But I think that would be easier for you to handle anyways, knowing you would always expect an array.



回答3:

Not 100% I know what your aiming for but I'll take a stab at it. Is this what you mean..

Demo

$scope.content = {
      things: [
          {
              thing: 'one',
              thingType: 'load'
          },
          {
              thing: 'two',
              thingType: 'export'
          },
          {
              thing: 'three',
              thingType: 'export'
          }
      ]
  }

  $scope.groups = {};
  $scope.group  = group;


  function group(){

    angular.forEach($scope.content.things, function(thing){

      if($scope.groups.hasOwnProperty(thing.thingType)){
        $scope.groups[thing.thingType].push(thing);
      } else {
        $scope.groups[thing.thingType] = [thing];
      }

    });


  }