Help us understand the problem. What is going on with this article?

Ember.jsが提供するEnumerableインターフェイス

More than 5 years have passed since last update.

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++!!)

kmdsbng
京都で働いてるプログラマです
http://twitter.com/kmdsbng
mmj
ウェブシステム開発やサービスを運営している京都の会社です。Kotlin, TypeScript, Reactを中心とした開発体制への移行をしています。 その前はRuby on Rails を中心に開発をしていました。
https://www.mmj.ne.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away