代码之家  ›  专栏  ›  技术社区  ›  one-hand-octopus

访问和修改具有相同值的多个数组元素

  •  0
  • one-hand-octopus  · 技术社区  · 4 年前

    假设我有一个数组 a = [8, 3, true, 9, false] b = [1, 3, 4] . 是否可以这样做:

    a[b] = false;
    

    所以一个 [8, false, true, false, false]

    0 回复  |  直到 4 年前
        1
  •  3
  •   Nick Parsons Felix Kling    4 年前

    这种语法在这里不起作用,因为 b 是一个数组,JS将尝试并转换 B 通过调用 toString() 在那个阵列上。自从 b.toString() 导致 "1,3,4" 你最终会添加 "1,3,4" 作为数组中的属性:

    const a = [8, 3, true, 9, false];
    const b = [1, 3, 4];
    
    a[b] = false; // adds property "1,3,4" to the array `a`, sets it to false
    console.log(a["1,3,4"]); // false

    B ,以及该索引中的每个索引集 a forEach() :

    const a = [8, 3, true, 9, false];
    const b = [1, 3, 4];
    
    b.forEach(idx => a[idx] = false);
    console.log(a); // [8, false, true, false, false]

    如果您想保持此不变,而不修改原始数组,可以使用 Object.assign() B :

    const a = [8, 3, true, 9, false];
    const b = [1, 3, 4];
    
    const res = Object.assign([], a, ...b.map(idx => ({[idx]: false})));
    console.log(res);
        2
  •  0
  •   customcommander    4 年前

    const at = (ii, y) => (x, i) => ii.includes(i) ? y : x;
    

    它是一个curried函数,它获取索引列表 ii y 对于这些索引。然后它返回一个接受值的函数 x 和一个索引 i 属于 二, 然后返回新值 否则保持价值 x .

    这样,在映射数组时可以方便地将其内联:

    [8, 3, true, 9, false].map(at([1, 3, 4], false));
    //  ^        ^  ^
    //  1        3  4
    //
    //=> [8, false, true, false, false]
    

    如果您希望能够在不同的索引中分配不同的值,那么我们可以使用以下数据结构:

    [[xi, xv], [yi, yv], [zi, zv], ...] 
    

    为了支持这一点,我们需要重写 at .

    (x, i) 它试图找到第一个el所在的一对。等于 [, x] . 最后访问该对中的第二个元素,它将是该索引处的值。

    const at = (...ys) => (x, i) => (ys.find(([j]) => j === i) || [, x])[1];
    

    我们仍然可以按上述方式将其内联:

    [8, 3, true, 9, false].map(at([1, 'x'], [3, 'y'], [4, 'z']));
    //  ^        ^  ^
    //  1        3  4
    //  x        y  z
    //
    // [8, "x", true, "y", "z"]