上記の受け入れられた回答に加えて、underscore.js ライブラリを使用して一般的な「groupBy」フィルターを作成しました。
JSFiddle (更新):
http://jsfiddle.net/TD7t3/
フィルター
app.filter('groupBy', function() {
return _.memoize(function(items, field) {
return _.groupBy(items, field);
}
);
});
'memoize' 呼び出しに注意してください。このアンダースコア メソッドは、関数の結果をキャッシュし、angular が毎回フィルター式を評価するのを停止します。これにより、angular がダイジェストの反復制限に達するのを防ぎます。
html
<ul>
<li ng-repeat="(team, players) in teamPlayers | groupBy:'team'">
{{team}}
<ul>
<li ng-repeat="player in players">
{{player.name}}
</li>
</ul>
</li>
</ul>
「team」プロパティの teamPlayers スコープ変数に「groupBy」フィルターを適用します。ng-repeat は、次の反復で使用できる (key, values[]) の組み合わせを受け取ります。
更新 2014 年 6 月 11 日
キーとしての式の使用 (ネストされた変数など) を考慮して、フィルターによるグループを拡張しました。angular parse サービスは、これに非常に役立ちます。
フィルター (式のサポートあり)
app.filter('groupBy', function($parse) {
return _.memoize(function(items, field) {
var getter = $parse(field);
return _.groupBy(items, function(item) {
return getter(item);
});
});
});
コントローラー (ネストされたオブジェクトを使用)
app.controller('homeCtrl', function($scope) {
var teamAlpha = {name: 'team alpha'};
var teamBeta = {name: 'team beta'};
var teamGamma = {name: 'team gamma'};
$scope.teamPlayers = [{name: 'Gene', team: teamAlpha},
{name: 'George', team: teamBeta},
{name: 'Steve', team: teamGamma},
{name: 'Paula', team: teamBeta},
{name: 'Scruath of the 5th sector', team: teamGamma}];
});
html (sortBy 式を使用)
<li ng-repeat="(team, players) in teamPlayers | groupBy:'team.name'">
{{team}}
<ul>
<li ng-repeat="player in players">
{{player.name}}
</li>
</ul>
</li>
JSFiddle:
http://jsfiddle.net/k7fgB/2/