web-dev-qa-db-ja.com

RxJSでの `map`メソッドの意味は何ですか?

私は RxJS このチュートリアルを読むことでhttp://reactive-extensions.github.io/learnrx/を学んでいます。

Observableの-​​ map メソッドを理解するのに苦労しています。 Arraymapバージョンは、本当にシンプルで簡単です。 mapの場合にObservableが正確に何を意味するのかわかりません(そしてなぜselect ?!という名前のエイリアスがあるのですか?)。

これは、ドキュメントが私に言ったことです。ほとんどの初心者には役に立たないかもしれません...

要素のインデックスを組み込むことにより、オブザーバブルシーケンスの各要素を新しいフォームに投影します。これは、選択メソッドのエイリアスです。

mapのコンテキストでeventが理解できません。たとえば、以下のコードは私が期待したとおりに機能します。このコードは、「click-eventのイベントストリームから#btnを聴く」と考えました。

var btnClicks, observable;

btnClicks = Rx.Observable.fromEvent($('#btn'), "click");

observable = btnClicks.subscribe(function(e) {
        console.log(e);
});

しかし、これになるとどうなりますか?

var btn2Clicks, btnClicks, observable;

btnClicks = Rx.Observable.fromEvent($('#btn'), "click");

btn2Clicks = Rx.Observable.fromEvent($('#btn2'), "click");

observable = btnClicks.map(function(e) {
  return btn2Clicks;
}).subscribe(function(e) {
  console.log(e);
});

私が考えたのは、mapを使用して、クリックイベントのコレクションを別のイベントコレクションのコレクションに変換することです。 filterは理解しやすいです。Wordfilterが意味するように、興味のあるイベントだけを受け取り、他のイベントはスキップします。しかし、mapのコンテキストでeventはどうですか?配列バージョンと同じように「コレクションを別のコレクションに変換する」ことを意味する場合、#btnがクリックされたときにまだコレクションが起動するのはなぜですか?

私はそれを別のコレクションにマッピングしたことを意味し、今では#btnのクリックイベントのコレクションではありませんが、何かの新しいコレクションです...しかし、#btnがクリックされたときに起動私にとって意味があります。

24
yaquawa

mapは、Observablesでも配列とまったく同じように機能します。 mapを使用して、アイテムのコレクションを異なるアイテムのコレクションに変換します。少なくともオブザーバーの観点からは、Observableをアイテムのコレクション(配列もアイテムのコレクションであるように)と考えると役立ちます。

たとえば、いくつかの配列で使用するために作成した次の2つのメソッドを使用します。

function multiplyByTwo(collection) {
    return collection.map(function (value) {
        return value * 2;
    });
}

function removeZeroes(collection) {
    return collection.filter(function (value) {
        return value !== 0;
    });
}

var a = [1, 2, 3, 4, 0, 5];
var b = multiplyByTwo(a); // a new array [2, 4, 6, 8, 0, 10]
var c = removeZeroes(b); // a new array [2, 4, 6, 8, 10]

オブザーバブルには、これらの同じ関数を使用できます。

var a = Rx.Observable.of(1, 2, 3, 4, 0, 5);
var b = multiplyByTwo(a); // a new observable [2, 4, 6, 8, 0, 10]
var c = removeZeroes(b); // a new observable [2, 4, 6, 8, 10]

これは、RxJのオブザーバブルがmapfilterなどの配列演算子を実装して、配列の場合とまったく同じセマンティクスを持つために可能です。それらが配列に対してどのように機能するかを知っていれば、オブザーバブルに対してどのように機能するかを知っています。

このトリックは、 observablesとenumerablesの二重の性質 の結果です。

表示しているインタラクティブなチュートリアルを実行する場合、実際にこのプロセスを順を追って説明します。配列用のマップ演算子を書くことから始め、その後のチュートリアルでソースとしてオブザーバブルを潜入すると思います。

追伸これは、その歴史からselectのエイリアスです。ReactiveExtensionsは最初に.NETで実装され、後に他の言語に移植されました。 Rx.NETは、.NETのLINQで使用されるものと同じ演算子を使用します(IObservableIEnumerableの双対であるため)。 LINQのマップ演算子はSelectとして知られています(そしてそのフィルター演算子はWhereとして知られています)。これらの名前は、LINQの起源に由来します。 LINQが構築されたときの目標の1つは、C#でデータベースクエリを作成できるようにすることでした。したがって、多くの演算子にSQL命名規則を採用しました(LINQ SELECTはSQL SELECTに直接マップされ、LINQ WHEREはSQL WHEREにマップされますなど)。

35
Brandon

投影に使用されるRxjsのマップは、配列をまったく新しい配列に変換できることを意味します。 Mapの仕組みを理解するために、プレーンなJavaScriptを使用して独自のマップ関数を実装できます。

Array.prototype.map = function(projectionFunction){
var results=[];
this.forEach(function(item) {
results.Push(projectionFunction(item));
});
return results;
};

パラメータとして匿名関数を受け入れるマップ関数を作成したことがわかります。これは、配列を変換する投影を適用する関数です。マップ関数内では、配列内の各アイテムを繰り返し表示し、各アイテムを渡すことでプロジェクト関数を呼び出します。最後に、投影関数の結果が結果配列にプッシュされます。

JSON.stringify([1,2,3].map(function(x){return x+1;}))

出力

[2,3,4]
3
Code-EZ