#javascript
#javascript
Вопрос:
Допустим, у меня есть массив a = [8, 3, true, 9, false]
и массив индексов b = [1, 3, 4]
. Возможно ли сделать что-то подобное:
a[b] = false;
Так что a становится [8, false, true, false, false]
?
Комментарии:
1. Не напрямую, нет. Вы можете использовать
forEach
:b.forEach(idx => a[idx] = false);
или аналогичный
Ответ №1:
Этот синтаксис здесь не будет работать, поскольку 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
false. Это можно сделать с помощью обычного цикла for или 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:
В языке нет встроенной поддержки, но вы можете легко написать функцию для этого.
const at = (ii, y) => (x, i) => ii.includes(i) ? y : x;
Это функция curried, которая принимает список индексов ii
и новое значение y
для этих индексов. Затем он возвращает функцию, которая принимает значение x
и индекс i
. Если i
принадлежит ii
, то возвращает новое значение y
, в противном случае сохраняет значение 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)
он пытается найти пару, где 1-й el. равно i
. Если есть результат, верните пару, в противном случае верните временную пару [, x]
. Наконец, получите доступ ко 2-му элементу пары, который будет значением по этому индексу.
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"]