Ember.jsは配列みたいなデータを便利に扱うための、Enumerable interfaceを提供しています。
rubyのEnumerableと同じようなやつです。
Ember.jsはArrayに対してEnumerable interfaceを組み込んでいます。なので、配列に対してEnumerableの機能を利用することができます。
配列の他には、Ember.ArrayProxy, Ember.SetなどにEnumerable interfaceが組み込まれています。
今日はEnumerableが提供するメソッドを紹介します。
forEach, map, reduce
Ember.jsは、forEach, map, reduceが実行環境で組み込みで提供されていれば、組み込みのメソッドを使い、実装されてなければ独自の実装を提供します。
ブラウザ互換性を考えずに使えるので良いですね。
invoke
invokeは、引数に渡された名前のメソッドを、各要素に対して呼び出します。
結果を得るためでなく、副作用のある処理を実行するために利用します。
玄人好みな感じのメソッドですね。
Person = Ember.Object.extend({
sayHello: function() {
console.log("Hello from " + this.get('name'));
}
});
var people = [
Person.create({ name: "Juan" }),
Person.create({ name: "Charles" }),
Person.create({ name: "Majd" })
]
people.invoke('sayHello');
// Hello from Juan
// Hello from Charles
// Hello from Majd
firstObject, lastObject
最初と最後の要素を返す。
[1,2,3].get('firstObject') // 1
[1,2,3].get('lastObject') // 3
toArray
配列に変換します。
setEach, getEach
setEachは、各要素のメンバに対して同じ値をセットします。
getEachは、各要素のメンバを取得します。
こういう処理を簡単に書けるのは嬉しいですね。
var arr = [Ember.Object.create(), Ember.Object.create()];
// we now have an Array containing two Ember.Objects
arr.setEach('name', 'unknown');
arr.getEach('name') // ['unknown', 'unknown']
filter
rubyでいうselectです。
var arr = [1,2,3,4,5];
arr.filter(function(item, index, self) {
if (item < 4) { return true; }
})
// returns [1,2,3]
filterProperty
filterで値一致を行うための簡潔記法です。
第二引数を指定しないと、 !!value が真になるものを抽出します。
Todo = Ember.Object.extend({
title: null,
isDone: false
});
todos = [
Todo.create({ title: 'Write code', isDone: true }),
Todo.create({ title: 'Go to sleep' })
];
todos.filterProperty('isDone', true);
// returns an Array containing just the first item
every, some
rubyでいう all? と any? です。
Person = Ember.Object.extend({
name: null,
isHappy: false
});
var people = [
Person.create({ name: 'Yehuda', isHappy: true }),
Person.create({ name: 'Majd', isHappy: false })
];
people.every(function(person, index, self) {
if(person.get('isHappy')) { return true; }
});
// returns false
compact
rubyでいうcompactです。
nullである要素を除去します。
[1, null, undefined, 2].compact()
// [1, undefined, 2]
undefinedを除去しないのはダメな感じですね。
uniq
重複する要素を除去します。
var arr = ["a", "a", "b", "b"];
arr.uniq(); // => ["a", "b"]
without
渡された値と一致する要素を除去します。
var arr = ["a", "b", "a", "c"];
arr.without("a"); // => ["b", "c"]
以上です。
配列に組み込まれているので、特になにも考慮しなくても使えるのが嬉しいですね。
個人的には、思ってたより便利な機能が揃っているので、使えそうな感じだと思います。
ただ、prototypeは汚染されてしまうので、Ember.jsを使うときは、for in を使うときにはhasOwnPropertyに一致するものだけを対象にするように注意しないといけません。
property汚染をしないようにするオプションも用意されています。この記事のコメント欄を参照してください。(ursm++!!)