V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
muunala10221
V2EX  ›  JavaScript

请问 JS 如何合并这样的两个数组

  •  
  •   muunala10221 · 2021-08-11 09:30:27 +08:00 · 1843 次点击
    这是一个创建于 1201 天前的主题,其中的信息可能已经有所发展或是发生改变。
    let a = [[123, ''],[456, ''],[789, '']]
    let b = [[123, 1],[456, 1] ]

    a 一定包含 b 的所有值,想要把 ab 合并 ,最后变成 [[123, ''],[456, 1],[789, ''],我知道循环可以做到,但是想看看有啥更优雅的实现方法没
    第 1 条附言  ·  2021-08-11 11:18:51 +08:00
    打错了 应该是 [[123, 1],[456, 1],[789, '']],另外感谢 1 楼 我没办法回复
    16 条回复    2021-08-16 12:04:16 +08:00
    codehz
        1
    codehz  
       2021-08-11 09:46:02 +08:00 via Android   ❤️ 3
    [...new Map([...a, ...b])]
    neekeV2
        2
    neekeV2  
       2021-08-11 10:30:51 +08:00
    @codehz 这什么骚操作
    otakustay
        3
    otakustay  
       2021-08-11 10:54:35 +08:00
    @neekeV2 利用 Map 在 key 相同的时候会后者覆盖前者呗
    sgiyy
        4
    sgiyy  
       2021-08-11 10:55:16 +08:00
    [123, ''] [123, 1] > [123, '']
    [456, ''] [456, 1] > [456, 1]

    这是什么回事?
    muunala10221
        5
    muunala10221  
    OP
       2021-08-11 11:20:23 +08:00
    @sgiyy 打错咯 应该是 [[123, 1],[456, 1],[789, '']]
    muunala10221
        6
    muunala10221  
    OP
       2021-08-11 11:20:30 +08:00
    @codehz 感谢
    libook
        7
    libook  
       2021-08-11 11:51:18 +08:00   ❤️ 2
    #1 楼是把[123,""]这种数组的第 0 位元素作为 Map 的 key,第 1 位元素作为 Map 的 value,挺巧妙的。
    Map 对比 key 一样不一样的时候用的是 Object.is ,几乎和强逻辑等===是一样的,只不过在+0 、-0 以及 NaN 上结果不一样,所以如果是[[123],""]这种更复杂的形态就不行了。

    同理,有个更简单的写法,是利用的 Object 里 key 唯一的原理:
    Object.assign([],a,b);
    能某种程度上解决上面的问题,但也不能说这个就是很稳的方法,这种用法肯定不是语言本身设计的初衷,得了解清楚为什么是这个结果才行,比如 key 为什么能判定为一样( ES2022 没有写明判断细节,只在 10.1.5.1 (2) 一句“If O does not have an own property with key P, return undefined.” 所以很可能未来引擎实现变化了,这个结果也会变化),上游原型上的 key 是否也可以,遇到 getter 、setter 会不会有问题,数组里的元素是引用的时候是否有问题。

    不知道题主怎么定义“优雅”,这么做很巧妙,但是团队协作的时候不容易看懂,你最好多写一些注释标明这一句是在干嘛……
    libook
        8
    libook  
       2021-08-11 12:42:37 +08:00
    @libook #7 额,我给的答案有问题,Object.assign 是直接识别的数组 index,比如[[123], '']在 a 数组里的 index 是 0,[123, 1]在 b 数组里的 index 是 0,assign 单纯把 b 的 0 位元素覆盖到了 a 的 0 位元素,如果把数组内元素的顺序打乱,就不行了……
    muunala10221
        9
    muunala10221  
    OP
       2021-08-11 14:11:06 +08:00
    @libook 好的 谢谢你
    jjwjiang
        10
    jjwjiang  
       2021-08-11 15:16:21 +08:00
    @codehz 这个不是有明显的问题吗?如果楼主给的数组第二项不一样的话也会合并覆盖了,这个写法只看每个元素的第一项
    muunala10221
        11
    muunala10221  
    OP
       2021-08-11 17:16:51 +08:00
    @jjwjiang 嗯嗯,我期望的就是这样,需求是前端监控页面,近七天数据图表,后端说可能无法从普罗米修斯获取近 7 天的全部数据,中途机器可能 down 掉,这时需要我从用户选择的时间起止范围计算时间戳 360 个点,再和后端接口对比,后端返回有数据的点我放在这 360 个点中,所以数组 1 下标不太重要 只要 0 相同的合并就好啦
    UnitTest
        12
    UnitTest  
       2021-08-11 19:33:35 +08:00
    我没看懂题目啊,a 一定包含 b, 那 ab 还有什么合并的意义呢?
    UnitTest
        13
    UnitTest  
       2021-08-11 19:35:10 +08:00
    哦,明白了,二维数组里面第 0 个元素其实是 Key,第 1 个元素其实是 value 。
    shilianmlxg
        14
    shilianmlxg  
       2021-08-12 08:40:24 +08:00 via iPhone
    我记得 lodash 有 api ( cv 工程师的肯定)
    lin07hui
        15
    lin07hui  
       2021-08-16 11:49:59 +08:00
    @shilianmlxg _.uniqBy([...b, ...a], '0')
    shilianmlxg
        16
    shilianmlxg  
       2021-08-16 12:04:16 +08:00 via iPhone
    @lin07hui 谢谢大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2897 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:02 · PVG 17:02 · LAX 01:02 · JFK 04:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.