JavaScript学习之的惰性数组详解
来源:互联网 发布:万字酱油 知乎 编辑:程序博客网 时间:2024/06/06 03:47
本文和大家分享的主要是javascript中惰性数组相关内容,一起来看看吧,希望对大家学习javascript有所帮助。
什么是惰性数组,它为什么有用?
我们来重现一下你第一次面试软件工程师时的题目:写一个斐波纳契函数。我们明确了0和1的基本情况,然后递归生成剩下的:
let fib = n => {
switch (n) {
case 0: return 0
case 1: return 1
default: return fib(n - 1) + fib(n - 2)
}
}
小菜一碟。
这种解决方案有什么问题吗?还用说么 - 效率真的真的很低。要计算第n个斐波那契数字,我们要调用 fib 函数 2的n-1幂次!简直糟糕的要命,我们应该做的更好一点。
一种方法是记录 fib 的输出。就是说,由于 fib 是纯粹和幂等的,我们可以缓存其输出:
let memoize = fn => {
let cache = new Map
return _ => {
if (!cache.has(_)) {
cache.set(_, fn(_))
}
return cache.get(_)
}
}
let fib = memoize(n => {
switch (n) {
case 0: return 0
case 1: return 1
default: return fib(n - 1) + fib(n - 2)
}
})
好多了!现在我们输入为n时,只需调用 fib n - 1次。
我们还能怎么表达这种思想呢?
懒序列
在Scale中,你可以这样做(这得归功于 Philipp Gabler ):
def fib(n: Int): Stream[Int] = {
lazy val stream: Stream[Int] = 0 #:: stream.scan(1)(_ + _)
stream.take(n)
}
上面做的事情就是定义一个惰性的数据流(两个初始数字,加上一个能产生更多数字的函数),当调用 fib(n)时,它返回第n个数字,或者如果还没有计算,就生成并返回它。另一种思考方式是用生成器和一个记录先前产生值的缓存,这样之后就可以通过值的索引进行访问。
惰性流是一个非常酷的抽象概念,对于计算开销昂贵的序列,或者是不可能计算所有索引的序列都有效(即:无限序列)。这在功能性语言中很受欢迎,特别是默认具有惰性求值的语言。比如在Haskell中就是这样做:
fibs :: [Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
同样的思维,但在Clojure就是这样:
(defn fib []
((fn rfib [a b]
(cons a (lazy-seq (rfib b (+ a b)))))
0 1))
你大概明白了吧。
那在JavaScript中怎么用呢?
JavaScript中的惰性序列
通过 lazy-arr ,你可以像这样:
let fibs = lazy([0, 1])(_ => fibs[_ - 1] + fibs[_ - 2])
就这样!然后,您可以根据需要访问数组中的项,并根据需要进行计算:
fibs[10] // 55fibs[7] // 13
第一行计算第10个斐波纳契数,并且由于我们递归地进行计算的定义(按照以前的斐波那契数),我们需要计算前9个斐波那契数,以此来计算第10个。所以当我们在第二行计算第七个斐波纳契数时,结果会立即返回,因为我们已经计算好了!
最重要的是,就用户关心的来说, fibs 数组并不会做任何懈怠地、有状态地或递归地或其他类似的事情。它只是一个数组。那些麻烦的东西被lazy-arr封装好了,生成器就是一行代码。
来源:众成翻译
- JavaScript学习之的惰性数组详解
- 【JavaScript】实现一个数组惰性求值库
- Python学习之惰性求值
- 学习Javascript:掌握惰性函数定义模式
- JavaScript学习之数组
- javascript学习之数组
- Android控件详解之惰性装载控件
- JavaScript学习之二进制的 AST详解
- javascript 学习之函数的参数详解
- python学习笔记(24)--类的详解6-惰性属性
- Javascript设计模式-b惰性模式(机器学习)
- JavaScript 惰性载入函数
- JavaScript 函数惰性载入
- JavaScript 函数惰性载入
- JavaScript函数惰性载入
- JavaScript 惰性载入函数
- javaScript函数惰性加载
- javascript中的惰性求值
- python+pandas+时间、日期以及时间序列处理
- input type为text 时只能输入数字
- 深入理解操作系统原理之进程管理(二)
- 数据库使用及JDBC与数据库的连接
- 百度2017春招笔试真题编程题集合--Python
- JavaScript学习之的惰性数组详解
- HISI3516A与HISI3519支持的交叉编译工具链
- HDU 2892 area(凸多边形与圆的并)
- abstract抽象类和abstract抽象方法
- 比特位操作——二进制中有多少个1
- AT指令(中文详解版)
- Javascript之面向对象
- [Python学习]解释器Interpreter
- python小爬虫