电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

如何用JavaScript實(shí)現(xiàn)一個(gè)數(shù)組惰性求值庫(kù)

瀏覽:7日期:2023-06-04 16:02:50
概述

在編程語言理論中,惰性求值(英語:Lazy Evaluation),又譯為惰性計(jì)算、懶惰求值,也稱為傳需求調(diào)用(call-by-need),是一個(gè)計(jì)算機(jī)編程中的一個(gè)概念,它的目的是要最小化計(jì)算機(jī)要做的工作。它有兩個(gè)相關(guān)而又有區(qū)別的含意,可以表示為“延遲求值”和“最小化求值”,除可以得到性能的提升外,惰性計(jì)算的最重要的好處是它可以構(gòu)造一個(gè)無限的數(shù)據(jù)類型。

看到函數(shù)式語言里面的惰性求值,想自己用JavaScript寫一個(gè)最簡(jiǎn)實(shí)現(xiàn),加深對(duì)惰性求值了解。用了兩種方法,都不到 80 行實(shí)現(xiàn)了基本的數(shù)組的惰性求值。

怎么實(shí)現(xiàn)

惰性求值每次求值的時(shí)候并不是返回?cái)?shù)值,而是返回一個(gè)包含計(jì)算參數(shù)的求值函數(shù),每次到了要使用值得時(shí)候,才會(huì)進(jìn)行計(jì)算。

如何用JavaScript實(shí)現(xiàn)一個(gè)數(shù)組惰性求值庫(kù)

當(dāng)有多個(gè)惰性操作的時(shí)候,構(gòu)成一個(gè)求值函數(shù)鏈,每次求值的時(shí)候,每個(gè)求值函數(shù)都向上一個(gè)求值函數(shù)求值,返回一個(gè)值。最后當(dāng)計(jì)算函數(shù)終止的時(shí)候,返回一個(gè)終止值。

如何用JavaScript實(shí)現(xiàn)一個(gè)數(shù)組惰性求值庫(kù)

具體實(shí)現(xiàn)判斷求值函數(shù)終止

每次求值函數(shù)都會(huì)返回各種數(shù)據(jù),所以得使用一個(gè)獨(dú)一無二的值來作為判斷流是否完成的標(biāo)志。剛好 Symbol() 可以創(chuàng)建一個(gè)新的 symbol ,它的值與其它任何值皆不相等。

const over = Symbol();const isOver = function (_over) { return _over === over;}生成函數(shù) range

range 函數(shù)接受一個(gè)起始和終止參數(shù),返回一個(gè)求值函數(shù),運(yùn)行求值函數(shù)返回一個(gè)值,終止的時(shí)候返回終止值。

const range = function (from, to) { let i = from; return function () { if (i < to) { i++ console.log(’ranget’, i); return i } return over; }}轉(zhuǎn)換函數(shù) map

接受一個(gè)求值函數(shù)和處理函數(shù),獲取求值函數(shù) flow 中的數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行處理,返回一個(gè)流。

const map = function (flow, transform) { return function () { const data = flow(); console.log(’mapt’, data); return isOver(data) ? data : transform(data); }}過濾函數(shù) filter

接受一個(gè)求值函數(shù),對(duì)求值函數(shù) flow 中數(shù)據(jù)進(jìn)行過濾,找到符合的數(shù)據(jù)并且返回。

const filter = function (flow, condition) { return function () { while(true) { const data = flow(); if (isOver(data)) {return data; } if(condition(data)) {console.log(’filtert’, data);return data; } } }}中斷函數(shù) stop

接受一個(gè)求值函數(shù),當(dāng)達(dá)到某個(gè)條件時(shí)中斷,可以用閉包函數(shù)加上 stop 函數(shù)接著實(shí)現(xiàn)一個(gè) take 函數(shù)。

const stop = function (flow, condition) { let _stop = false; return function () { if (_stop) return over; const data = flow(); if (isOver(data)) { return data; } _stop = condition(data); return data; }}const take = function(flow, num) { let i = 0; return stop(flow, (data) => { return ++i >= num; });}收集函數(shù) join

因?yàn)榉祷氐亩际且粋€(gè)函數(shù),最后得使用一個(gè) join 函數(shù)來收集所有的值并且返回一個(gè)數(shù)組。

const join = function (flow) { const array = []; while(true) { const data = flow(); if (isOver(data)) { break; } array.push(data); } return array;}測(cè)試:

const nums = join(take(filter(map(range(0, 20), n => n * 10), n => n % 3 === 0), 2));console.log(nums);

輸出:

range  1

map    1

range  2

map    2

range  3

map    3

filter     30

range  4

map    4

range  5

map    5

range  6

map    6

filter     60

更優(yōu)雅的實(shí)現(xiàn)

上面使用 函數(shù) + 閉包 實(shí)現(xiàn)了惰性求值,但是還是不夠優(yōu)雅,絕大部分代碼都放到迭代和判斷求值是否完成上面去了。其實(shí) es6 中還有更好方法來實(shí)現(xiàn)惰性求值,就是使用 generator,generator 已經(jīng)幫我們解決了迭代和判斷流是否完成,我們就可以專注于邏輯,寫出更簡(jiǎn)潔易懂結(jié)構(gòu)清晰的代碼。

const range = function* (from, to) { for(let i = from; i < to; i++) { console.log(’ranget’, i); yield i; }}const map = function* (flow, transform) { for(const data of flow) { console.log(’mapt’, data); yield(transform(data)); }}const filter = function* (flow, condition) { for(const data of flow) { console.log(’filtert’, data); if (condition(data)) { yield data; } }}const stop = function*(flow, condition) { for(const data of flow) { yield data; if (condition(data)) { break; } }}const take = function (flow, number) { let count = 0; const _filter = function (data) { count ++ return count >= number; } return stop(flow, _filter);}

還得加上鏈?zhǔn)秸{(diào)用才算是完成了。

class _Lazy{ constructor() { this.iterator = null; } range(...args) { this.iterator = range(...args); return this; } map(...args) { this.iterator = map(this.iterator, ...args); return this; } filter(...args) { this.iterator = filter(this.iterator, ...args); return this; } take(...args) { this.iterator = take(this.iterator, ...args); return this; } [Symbol.iterator]() { return this.iterator; }}function lazy () { return new _Lazy();}

最后再測(cè)試一下:

const nums = lazy().range(0, 100).map(n => n * 10).filter(n => n % 3 === 0).take(2);for(let n of nums) { console.log(’num:t’, n, ’n’);}

輸出:

range  0

map    0

filter     0

num:   0

range  1

map    1

filter     10

range  2

map    2

filter     20

range  3

map    3

filter     30

num:   30

好了,大功告成。

總結(jié)

這樣我們就完成了一個(gè)最簡(jiǎn)的數(shù)組惰性求值的庫(kù),這里只是簡(jiǎn)單實(shí)現(xiàn)了惰性求值,要放到工程中還需要添加很多細(xì)節(jié)。因?yàn)榇a不過 80 行,可以很清楚的了解惰性求值原理,還能加深對(duì)生成器的理解。

以上就是如何用JavaScript實(shí)現(xiàn)一個(gè)數(shù)組惰性求值庫(kù)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript實(shí)現(xiàn)數(shù)組惰性求值庫(kù)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 北京软件开发_软件开发公司_北京软件公司-北京宜天信达软件开发公司 | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 齿轮减速电机一体机_蜗轮蜗杆减速马达-德国BOSERL齿轮减速机带电机生产厂家 | 色谱柱-淋洗液罐-巴罗克试剂槽-巴氏吸管-5ml样品瓶-SBS液氮冻存管-上海希言科学仪器有限公司 | 广州展览设计公司_展台设计搭建_展位设计装修公司-众派展览装饰 广州展览制作工厂—[优简]直营展台制作工厂_展会搭建资质齐全 | NMRV减速机|铝合金减速机|蜗轮蜗杆减速机|NMRV减速机厂家-东莞市台机减速机有限公司 | 台湾Apex减速机_APEX行星减速机_台湾精锐减速机厂家代理【现货】-杭州摩森机电 | 辐射仪|辐射检测仪|辐射巡测仪|个人剂量报警仪|表面污染检测仪|辐射报警仪|辐射防护网 | 欧盟ce检测认证_reach检测报告_第三方检测中心-深圳市威腾检验技术有限公司 | 新型锤式破碎机_新型圆锥式_新型颚式破碎机_反击式打沙机_锤式制砂机_青州建源机械 | 手术室净化厂家-成都做医院净化工程的公司-四川华锐-15年特殊科室建设经验 | 济南货架定做_仓储货架生产厂_重型货架厂_仓库货架批发_济南启力仓储设备有限公司 | 爱佩恒温恒湿测试箱|高低温实验箱|高低温冲击试验箱|冷热冲击试验箱-您身边的模拟环境试验设备技术专家-合作热线:400-6727-800-广东爱佩试验设备有限公司 | 真空干燥烘箱_鼓风干燥箱 _高低温恒温恒湿试验箱_光照二氧化碳恒温培养箱-上海航佩仪器 | 深圳公司注册-工商注册公司-千百顺代理记账公司 | 污水处理设备维修_污水处理工程改造_机械格栅_过滤设备_气浮设备_刮吸泥机_污泥浓缩罐_污水处理设备_污水处理工程-北京龙泉新禹科技有限公司 | 天津试验仪器-电液伺服万能材料试验机,恒温恒湿标准养护箱,水泥恒应力压力试验机-天津鑫高伟业科技有限公司 | 直齿驱动-新型回转驱动和回转支承解决方案提供商-不二传动 | 健康管理师报名入口,2025年健康管理师考试时间信息网-网站首页 塑料造粒机「厂家直销」-莱州鑫瑞迪机械有限公司 | 圆窗水平仪|伊莉莎冈特elesa+ganter | 澳洁干洗店加盟-洗衣店干洗连锁「澳洁干洗免费一对一贴心服务」 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 宽带办理,电信宽带,移动宽带,联通宽带,电信宽带办理,移动宽带办理,联通宽带办理 | 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 深圳活动策划公司|庆典策划|专业公关活动策划|深圳艺典文化传媒 重庆中专|职高|技校招生-重庆中专招生网 | 雷冲击高压发生器-水内冷直流高压发生器-串联谐振分压器-武汉特高压电力科技有限公司 | 协议书_协议合同格式模板范本大全 | 压装机-卧式轴承轮轴数控伺服压装机厂家[铭泽机械] | 苏州注册公司_苏州代理记账_苏州工商注册_苏州代办公司-恒佳财税 | 海德莱电力(HYDELEY)-无功补偿元器件生产厂家-二十年专业从事电力电容器 | 有机肥设备生产制造厂家,BB掺混肥搅拌机、复合肥设备生产线,有机肥料全部加工设备多少钱,对辊挤压造粒机,有机肥造粒设备 -- 郑州程翔重工机械有限公司 | 深圳公司注册-工商注册公司-千百顺代理记账公司 | 广东健伦体育发展有限公司-体育工程配套及销售运动器材的体育用品服务商 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 | 扬尘在线监测系统_工地噪声扬尘检测仪_扬尘监测系统_贝塔射线扬尘监测设备「风途物联网科技」 | 安规_综合测试仪,电器安全性能综合测试仪,低压母线槽安规综合测试仪-青岛合众电子有限公司 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 嘉兴泰东园林景观工程有限公司_花箱护栏| 高速龙门架厂家_监控杆_多功能灯杆_信号灯杆_锂电池太阳能路灯-鑫世源照明 | 比亚迪叉车-比亚迪电动叉车堆垛车托盘车仓储叉车价格多少钱报价 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 |