配列操作のためのフィルター
最後に、配列操作のための主なフィルターです。
分類 | フィルター | 概要 |
---|---|---|
基本 | concat : coll | 現在の配列に配列collを連結 |
defaults: props | 「名前: 値」の形式でプロパティのデフォルト値を設定 | |
join: sep | 配列内の要素を区切り文字sep(デフォルトはスペース)で連結 | |
isEmpty | 配列が空であるかを判定 | |
xor: coll: prop | 現在の配列を配列collと比較し、重複しない要素だけを取得(propは重複チェックに利用するプロパティ名) | |
検索 | contains: exp | 配列に条件式expに合致する要素が一つでも存在するか |
every: exp | 配列のすべての要素が条件式expに合致するか | |
filterBy: props :value | オブジェクト配列を対象のプロパティpropsと値valueの組み合わせで検索(propsはプロパティ名の配列、prop.subpropのようなネストキーも指定可) | |
first: num | 配列の先頭からnum件を取得 | |
first: exp | 配列から最初の要素を取得(条件式expを指定した場合は条件に合致した最初の要素) | |
last: num | 配列の末尾からnum件を取得 | |
last: exp | 配列から最後の要素を取得(条件式expを指定した場合は条件に合致した最後の要素) | |
加工 | flatten: shallow | 入れ子の配列をフラット化(shallowがtrueの場合、1階層のみ処理) |
countBy: props | オブジェクト配列を指定のプロパティをキーにグループ化し、グループ単位の件数を取得(propsはプロパティ名の配列、prop.subpropのようなネストキーも指定可) | |
groupBy: props | オブジェクト配列を指定のプロパティをキーにグルーピング(propsはプロパティ名の配列、prop.subpropのようなネストキーも指定可) | |
map: callback | 配列内の要素をコールバック関数callbackで加工 | |
reverse | 配列を逆順に並べ替え | |
除去 | omit: exp | 配列から条件式に合致する要素だけを除去 |
remove: obj:... | 配列から指定された要素obj...を除去 | |
unique :prop | プロパティpropをキーに重複した要素を配列から除去 |
以下では、これら、あまたあるフィルターの中でも、表だけでは分かりにくいものについて、いくつかピックアップしておきます。
オブジェクト配列をグループ化する
groupByフィルターは、オブジェクト配列を指定されたキーでグループ化し、「キー名: グループ配下のオブジェクト群」のハッシュを生成します。例えば以下は、メンバー情報membersを部署(departプロパティ)の単位にグループ化し、部署単位のメンバー情報を列挙します。
angular.module('myApp', ['angular.filter']) .controller('MyController', ['$scope', function($scope) { $scope.members = [ { name: '山田太郎', age: 40, email: 'tyamada@examples.com' }, { name: '鈴木健太', age: 20, email: 'ksuzuki@examples.com' }, { name: '藤原祐樹', age: 30, email: 'yfujiwara@examples.com' } ]; }]);
angular.module('myApp', ['angular.filter']) .controller('MyController', ['$scope', function($scope) { $scope.members = [ { id: 1, name: { first: '山田', last: 'さくら' }, depart: '総務部' }, { id: 2, name: { first: '鈴木', last: '太郎' }, depart: '人事部' }, { id: 3, name: { first: '佐藤', last: 'うめ' }, depart: '営業部' }, { id: 4, name: { first: '藤井', last: '次郎' }, depart: '総務部' }, { id: 5, name: { first: '伊藤', last: 'つばき' }, depart: '総務部' }, { id: 6, name: { first: '和田', last: '三郎' }, depart: '営業部' }, { id: 7, name: { first: '井上', last: 'もも' }, depart: '営業部' }, { id: 8, name: { first: '田中', last: '四朗' }, depart: '総務部' }, { id: 9, name: { first: '木下', last: 'はな' }, depart: '人事部' }, { id: 10, name: { first: '山口', last: '五郎' }, depart: '無所属' }, ]; }]);
▼
二重ループとなったng-repeatでは、外側ループでグループ化キー(key)とオブジェクト群(objs)を取り出し、内側ループでオブジェクト群(objs)から個々のメンバー情報を取り出しているわけです。
よく似たフィルターとしてcountByフィルターもあります。こちらは指定されたキーでオブジェクトをグループ化し、「キー名: 件数」のハッシュを返します。
複数プロパティ/ネストされたプロパティで検索する
Angular Filterのいくつかのフィルターでは、プロパティを指定する際にprop.subpropのようにサブプロパティを指定したり、プロパティ同士を連結して複合キーを指定したりできるものがあります。
例えば以下は、filterByプロパティを使ってメンバー情報membersから「山田さくら」を検索する例です。複数のプロパティ(この場合はfirst/last)を連結するには「+」演算子を利用します。
<p ng-repeat="member in members | filterBy: ['name.first + name.last']: '山田 さくら'"> {{ member.id }}:{{ member.name.first }}{{ member.name.last }} </p> <!--結果:1:山田さくら-->
注2
membersオブジェクト配列の内容は、group.jsと同じです。
条件にマッチした要素を除去する
omitフィルターを利用することで、条件式に合致した要素だけを配列から除去できます。例えば以下はメンバー情報から部署(departプロパティ)が「無所属」であるメンバーだけを除去する例です。
<ul> <li ng-repeat="member in members | omit: 'depart === \'無所属\''"> {{ member.id }}:{{ member.name.first }}{{ member.name.last }} </li> </ul>
▼
注3
membersオブジェクト配列の内容は、group.jsと同じです。
条件式はfunction型で指定することもできます。あらかじめ以下のような関数を準備した上で、リスト8の太字部分を「omit: nodepart」と書き換えてください。複雑な判定式を表すならば、このようにビューからは切り離すのが得策です。
$scope.nodepart = function(e) { return (e.depart === '無所属'); }
nodepart関数の引数eには、配列の要素が個々に渡されます。よって、e.departで部署にアクセスできるわけです。
まとめ
以上、本稿ではAngularJSで利用できるフィルター集Angular Filterについて解説しました。標準フィルターだけではなにかと不便だった点が、ぐんと実装しやすくなったのではないでしょうか。安易に自作に走る前に、まずはこうしたライブラリを活用することを検討してみると良いでしょう。
次回は、アコーディオンパネル/タブパネル/カルーセルなどなど、テキスト/画像を限られた領域でスマートに表示するためのウィジェット類について紹介します。
参考資料
- 『AngularJSアプリケーションプログラミング』(技術評論社)
- 『AngularJSライブラリ 活用レシピ 厳選 108』(WINGSプロジェクト)