数组多次 filter, 多次 map 混合链式调用过程中, 有没有办法只在最后一次调用时生成一次数组呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
bthulu
V2EX    Javascript

数组多次 filter, 多次 map 混合链式调用过程中, 有没有办法只在最后一次调用时生成一次数组呢?

  •  
  •   bthulu 2022-07-25 23:48:58 +08:00 3968 次点击
    这是一个创建于 1178 天前的主题,其中的信息可能已经有所发展或是发生改变。

    貌似每次 filter 或 map 都会返回一个新的数组, 对性能和内存 GC 影响很大. 不知有没有类似 Java 的 Lambda, C#的 Linq, 不论链式调用了多少次 filter, map, select, 都不会生成最终的数组或链表, 而是将这些条件判断函数 /方法存储起来, 直到遇到最后的终结点时, 才进行遍历, 依次匹配前面保存的条件判断, 最终返回一个数组或链表.

    25 条回复    2022-07-26 17:31:54 +08:00
    SoloCompany
        2
    SoloCompany  
       2022-07-26 00:20:04 +08:00 via iPad
    dcsuibian
        3
    dcsuibian  
       2022-07-26 00:21:13 +08:00
    用 for 循环写
    开玩笑的,都用上 js 这种高级语言了,正常使用不需要在乎这点性能,又不是刷算法题。
    hundandadi
        4
    hundandadi  
       2022-07-26 00:41:07 +08:00 via Android
    @dcsuibian 养成个好习惯还是有用的,前几天枚举类型 values 循环 filter 匹配的写法,线上 CPU 升高 10%,定位问题定位了两天才找出来,压测过不了很难受,所以能注意还是注意的好
    Leviathann
        5
    Leviathann  
       2022-07-26 00:47:07 +08:00
    最常用就 lodash 的 chain 咯
    autoxbc
        6
    autoxbc  
       2022-07-26 02:16:57 +08:00
    建议不要在乎性能,除非真的遇到性能问题,然后用单次 forEach 解决。至于 lodash ,使用这个东西,写出来的都不像 JS ,感觉就是完全不同的另一门语言
    isBitter
        7
    isBitter  
       2022-07-26 04:35:40 +08:00
    如果你的 filter map 传入的函数都是纯函数的话,可以把函数 compose 一遍,在调用。
    Magentaize
        8
    Magentaize  
       2022-07-26 07:40:18 +08:00 via iPhone
    RxJS ,就是你想要的
    masterclock
        9
    masterclock  
       2022-07-26 08:55:43 +08:00   1
    除非代码不能用了,否则绝不优化
    即使不能用了,先想想能不能升级硬件

    过早优化乃万恶之源
    bthulu
        10
    bthulu  
    OP
       2022-07-26 08:56:54 +08:00
    @masterclock 无法升级硬件, 部署到客户那边的, 客户随时可能拎出来一台 2000 年的奔腾机器给你
    echo1937
        11
    echo1937  
       2022-07-26 08:58:58 +08:00
    原来这个部分 JS 是没有惰性求值的,学习了。
    musi
        12
    musi  
       2022-07-26 09:01:52 +08:00
    你要不手写 for 循环吧
    ChefIsAwesome
        13
    ChefIsAwesome  
       2022-07-26 09:03:03 +08:00
    不是搞个 lazy 就能神奇的帮你优化的。这种工具库好多,你自己找个,测测耗时吧。
    dumbass
        14
    dumbass  
       2022-07-26 09:40:14 +08:00
    你要不手写 for 循环
    mxT52CRuqR6o5
        15
    mxT52CRuqR6o5  
       2022-07-26 09:41:49 +08:00 via Android
    是你真的碰到了性能问题还是你单纯的觉得这么写不好?
    Lodash 有个 chain 可以惰性求值不知道有多大优化
    你也可以手动 flatMap 把多次遍历合并成一次
    lin07hui
        16
    lin07hui  
       2022-07-26 10:52:03 +08:00
    @bthulu #10 2000 年的奔腾机器能用上现代浏览器吗?用 IE ?
    lmshl
        17
    lmshl  
       2022-07-26 10:53:31 +08:00
    我的 Scala 应用基本上都是每次链式调用求值一次列表,也没比别人 Java 少快几倍。

    而且 JS 有 VM + GC ,除非你跑过 perf 确认这里有性能瓶颈,不然我建议你不要瞎优化,可能适得其反。因为 Lazy evaluation 也是有 overhead 的,数据量小了不如立即求值。

    如果数据量真的大到有必要实施 lazy evaluation 的程度,那我也建议一步到位 RxJS
    ryougifujino
        18
    ryougifujino  
       2022-07-26 11:20:17 +08:00
    Rust 的话就会对这种情况优化,测出来甚至比直接 for 循环更快。
    hronro
        19
    hronro  
       2022-07-26 11:25:19 +08:00
    lazy.js 可以做到,不过这个库好久没维护了。

    https://github.com/dtao/lazy.js
    rrfeng
        20
    rrfeng  
       2022-07-26 12:08:03 +08:00 via Android
    超过三次我宁愿 for 写一遍,看起来更清晰。
    honhon
        21
    honhon  
       2022-07-26 14:01:38 +08:00
    你要不手写 for 循环吧
    molika
        22
    molika  
       2022-07-26 14:20:25 +08:00
    transducer
    bthulu
        23
    bthulu  
    OP
       2022-07-26 14:30:56 +08:00
    @lin07hui 用浏览器干嘛? 我这是跑后台服务, 控制厂内设备自动寻路的
    bthulu
        24
    bthulu  
    OP
       2022-07-26 14:33:29 +08:00
    @honhon 没法手写, 是个公共基类, 会不断有继承类对这个上层数组进行过滤处理. 基类是没法预知所有子类行为的
    frisktale
        25
    frisktale  
       2022-07-26 17:31:54 +08:00
    应该不行吧,又不是 linq
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2967 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 00:28 PVG 08:28 LAX 17:28 JFK 20:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86