简体   繁体   English

在AngularJS中对对象数组进行分组

[英]Group an array of objects in AngularJS

Based on an array looking like this: 基于如下所示的数组:

var members = [
  {name: "john", team: 1},
  {name: "kevin", team: 1},
  {name: "rob", team: 2},
  {name: "matt", team: 2},
  {name: "clint", team: 3},
  {name: "will", team: 3}
];

I need to create an unordered list for each team. 我需要为每个团队创建一个无序列表。

Can it be done directly with ngRepeat and a filter maybe? 可以直接用ngRepeat和过滤器完成吗?

Or is it easier to reorganize the array into an array of teams with a list of members? 或者更容易将数组重新组织成一个包含成员列表的团队数组?

var teams = [
  {id: 1, members: ["john", "kevin"]},
  {id: 2, members: ["rob", "matt"]},
  {id: 3, members: ["clint", "will"]}
]

The nested ngRepeat would be easy to implement, but how do I go from the first array to this one in a simple / clever manner? 嵌套的ngRepeat很容易实现,但是如何以简单/聪明的方式从第一个数组转到这个数组呢?

Note: The array doesn't come from the database but from an html table. 注意:该数组不是来自数据库,而是来自html表。 So it's just a flat list of members. 所以它只是一个简单的成员列表。

 function MyController() { this.members = [ {name: "john", team: 1}, {name: "kevin", team: 1}, {name: "rob", team: 2}, {name: "matt", team: 2}, {name: "clint", team: 3}, {name: "will", team: 3} ]; } angular.module('app', []); angular.module('app') .controller('MyController', MyController); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script> <div ng-app="app"> <div ng-controller="MyController as ctrl"> <ul> <li ng-repeat="member in ctrl.members">{{ member.name }} - {{ member.team }}</li> </ul> </div> </div> 

You have to group items. 你必须group项目。 For this, I used reduce method in order to create a hash collection which looks like this: 为此,我使用reduce方法创建一个如下所示的hash集合:

{
  "1": [
    "john",
    "kevin"
  ],
  "2": [
    "rob",
    "matt"
  ],
   "3": [
     "clint",
      "will"
   ]
}

The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value. reduce()方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。

The following step is to map this collection in an array . 以下步骤是将此集合maparray For this, you should use map method. 为此,您应该使用map方法。

The map() method creates a new array with the results of calling a provided function on every element in this array. map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数。

 var members = [ {name: "john", team: 1}, {name: "kevin", team: 1}, {name: "rob", team: 2}, {name: "matt", team: 2}, {name: "clint", team: 3}, {name: "will", team: 3} ]; var groups = members.reduce(function(obj,item){ obj[item.team] = obj[item.team] || []; obj[item.team].push(item.name); return obj; }, {}); var myArray = Object.keys(groups).map(function(key){ return {team: key, name: groups[key]}; }); console.log(myArray); 

Expanding over the @Alexandru-Ionut Mihai's answer, (just to experience how powerful a reduce function is).. here's a single reduce without having to map it again to achieve the same thing. 扩展了@ Alexandru-Ionut Mihai的答案,(只是为了体验一下reduce函数的强大功能)..这里只需要一个reduce而不必再次map它来实现同样的功能。 :) :)

 var members = [ {name: "john", team: 1}, {name: "kevin", team: 1}, {name: "rob", team: 2}, {name: "matt", team: 2}, {name: "clint", team: 3}, {name: "will", team: 3} ]; /*var teams = [ {id: 1, members: ["john", "kevin"]}, {id: 2, members: ["rob", "matt"]}, {id: 3, members: ["clint", "will"]} ]*/ var group_to_values = members.reduce(function(arr, item){ arr[item.team - 1] = arr[item.team - 1] || { id: item.team, members: []}; arr[item.team - 1].members.push(item.name); return arr; }, []); console.log(group_to_values); 

If you are using underscore.js, then you can use _.groupBy() method to group array of records on the basis of team. 如果您使用的是underscore.js,那么您可以使用_.groupBy()方法在团队的基础上对记录数组进行分组。

function MyController() {
  this.members = [
    {name: "john", team: 1},
    {name: "kevin", team: 1},
    {name: "rob", team: 2},
    {name: "matt", team: 2},
    {name: "clint", team: 3},
    {name: "will", team: 3}
  ];

var grouped = _.groupBy(this.members, function(member) {
  return member.team;
});
}

You can use a groupBy filter like this 您可以像这样使用groupBy过滤器

<ul ng-repeat="(key, value) in members | orderBy: 'team' | groupBy:ourGrouper">
      <li>{{key}}
        <ul>
          <li ng-repeat="mem in value | orderBy: 'name'">
            {{mem.name}}
          </li>
        </ul>
      </li>
    </ul>

See this FIDDLE 看到这个FIDDLE

 var members = [ {name: "john", team: 1}, {name: "kevin", team: 1}, {name: "rob", team: 2}, {name: "matt", team: 2}, {name: "clint", team: 3}, {name: "will", team: 3} ]; var groups = members.reduce(function(obj,item){ obj[item.team] = obj[item.team] || []; obj[item.team].push(item.name); return obj; }, {}); var myArray = Object.keys(groups).map(function(key){ return {team: key, name: groups[key]}; }); console.log(myArray); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM