NodeJSまとめ(3):シーケンスを迅速に生成する方法

4203 ワード

python、Rなどのプログラミング言語でシーケンスを持つ書き方に慣れていて、突然このような行為をJSに移植したいと思っています.NodeJSでは、[0-9]の配列をすばやく生成するには、最も速い書き方は:
//    [0,1,2,3,4,5,6,7,8,9]
[...Array[10].keys()]

上记の书き方については、「ステップ1.Array[10]は、undefined要素の10個の配列を返します.2.keys()は配列要素の反復器を返し、キー名の遍歴、配列、すなわちインデックスに使用される.3.…は、配列をパラメータ配列に変換するための拡張演算子(apply関数と理解してください)、すなわち0,1,2,3,4,5,6,7,8,9を表します.4.[]は、Array()メソッドを呼び出し、最後に10要素の配列を返すことを意味します.
したがって、上記の書き方は次のように書き換えることができます.
let array = Array(10),
    indexs = array.keys(),
    result = Array(...indexs)
//      
console.log(result)

では、10~20のシーケンスを取るには、次のような方法を採用することができます.
[...Array(21).keys()].slice(11)

明らかにこのような書き方はあまりにも非効率で、ストレージスペースを浪費しすぎて、ステップをカスタマイズすることができなくて、柔軟性も強くありません.それなら、拡張演算子のような文法を利用して、次の書き方で自分のシーケンスを定義することができますか?
//  2      ,20      ,3    
[...range(2, 20, 3)]

ここではES 6のiterator特性を十分に利用し,次のようなRange構造関数を定義することができる.
class Range {

    constructor(start, end, step) {
        this.start = start
        this.end = end
        this.step = step
    }

    /**
     *         ,           
     */
    [Symbol.iterator] () {
        let curr = this.start,
            _this = this
        return {
            next () {
                let result = curr < _this.end ? {
                    value : curr,
                    done : false 
                } : {
                    value : undefined,
                    done : true
                }
                curr = curr + _this.step
                return result
            }
        }
    }
}

Symbol.iteratorは拡張オブジェクトが反復モード列挙定数をサポートするため、Symbolタイプの一意性を維持するために上記の方法で参照する必要があります.
上記の書き方は機能を実現していますが、少しうるさいので、yieldで改善することができます.以下のようにします.
[Symbol.iterator] () {
    let curr = this.start,
        _this = this
    //       * 
    return function* () {
        //         
        while(curr < _this.end) {
            yield curr
            curr = curr + _this.step
        }
    }() //             
}

最後に、簡単な包装だけですべてのタスクを完了できます.
function range(start, end, step) {
    return new Range(start, end, step)
}

次に、カスタムシーケンスを使用できます.
//    [ 5, 10, 15, 20 ]
[...range(5, 25, 5)]
//    [ 100, 110, 120, 130, 140, 150, 160, 170, 180, 190 ]
[...range(100, 200, 10)]

結論
内蔵のSymbolを利用する.iteratorとyieldでは,カスタムシーケンス配列を簡単に構築できる.