NodeJS总结(三):一种快速生成序列的方法

习惯了python、R等编程语言自带序列的写法,突然想把这样的行为移植到JS中,在NodeJS中,如果要快速生成一个[0-9]的数组,那么最快捷的写法是:

//  生成[0,1,2,3,4,5,6,7,8,9]
[...Array[10].keys()]

对于上面的写法,理解分为[]步:
1. Array[10]返回一个10个undefined元素的数组;
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,我们可以轻易构造出自定义的序列数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值