Reputation: 4360
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?
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?
Note: The array doesn't come from the database but from an html table. 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>
Upvotes: 3
Views: 27734
Reputation: 11
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);
Upvotes: 1
Reputation: 7911
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. :)
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);
Upvotes: 6
Reputation: 48357
You have to group
items. For this, I used reduce
method in order to create
a hash
collection which looks like this:
{
"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.
The following step is to map
this collection in an array
. For this, you should use map
method.
The map() method creates a new array with the results of calling a provided function on every element in this array.
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);
Upvotes: 13
Reputation: 220
If you are using underscore.js, then you can use _.groupBy() method to group array of records on the basis of team.
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;
});
}
Upvotes: 3
Reputation: 4876
You can use a groupBy filter like this
<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
Upvotes: 2