Попытка создать копии массива с помощью оператора распространения, но кое-как мутирует массив - PullRequest
1 голос
/ 23 января 2020

Я пытаюсь попрактиковаться с понятием неизменности. Я использую массив spliceTest в качестве основной ссылки для создания копий массива и их изменения. Я подхожу к проблеме, когда объявляю переменную removeOneItem, я почему-то не могу объявить новую переменную распространения, используя ту же ссылку spliceTest.

const removeOneItem = [...spliceTest.splice(0,0), ...spliceTest.splice(1)];
const removeFive = [...spliceTest.splice(0,4), ...spliceTest.splice(5)];
const spreadTest = [...spliceTest];
console.log('removeOneItem:', removeOneItem)
  console.log('spreadTest:', spreadTest, spliceTest)
  console.log('removeFive:', removeFive)

Results::::::::::::
removeOneItem: [ 2, 3, 4, 5, 6, 7, 8, 9 ]
spreadTest: [] []
removeFive: [ 1 ]

Ответы [ 3 ]

3 голосов
/ 23 января 2020

Согласно MDN :

Метод splice () изменяет содержимое массива путем удаления или замены существующих элементов и / или добавления новых элементы на месте .

Это означает, что операция объединения изменяет ваш массив

2 голосов
/ 23 января 2020

Неизменность данных является краеугольным камнем функционального программирования, и в целом я сделаю то, что вы пытаетесь сделать: клонировать данные и мутировать клон. Следующая функция принимает массив и серию подмассивов. Подмассивы состоят из [startIndex, quantity]. Он клонирует исходный массив с помощью оператора распространения и склеивает клон в соответствии со вторым параметром (...cutDeep). Он вернет объект с исходным массивом и клонированным массивом. Если вы заключите все в функцию, то ваша область будет защищать каждый возврат. Замечание о последующих поворотах Второй клон (secondResult.dissected) объединяется еще раз, и последний журнал подтверждает, что исходный массив никогда не мутировал.

Демо

const data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];

const dissect = (array, ...cutDeep) => {
  let clone = [...array];
  for (let [cut, deep] of cutDeep) {
    clone.splice(cut, deep);
  }
  return {
    original: array,
    dissected: clone
  };
}

const firstResult = dissect(data, [2, 3], [5, 2], [9, 1]);

const secondResult = dissect(data, [3, 2], [10, 1]);

console.log(JSON.stringify(firstResult));

console.log(JSON.stringify(secondResult));

console.log(JSON.stringify(dissect(secondResult.dissected, [0, 2], [5, 1])));

console.log(JSON.stringify(data));
1 голос
/ 23 января 2020

Проблема в том, что вы используете splice, когда вы, скорее всего, хотите использовать slice.

splice используется для изменения массива в то время как slice используется для выбора подмассива.

const sliceTest = [1, 2, 3, 4, 5, 6, 7, 8, 9];

// select a sub-array starting from index 1 (dropping 0)
const removeOneItem = sliceTest.slice(1);

// select a sub-array starting from index 5 (dropping 0, 1, 2, 3, and 4)
const removeFive = sliceTest.slice(5);

// spread the full array into a new one
const spreadTest = [...sliceTest];

// array log helpers (leave these out in your code)
const toString = array => "[" + array.join(",") + "]";
const log = (name, ...arrays) => console.log(name, ...arrays.map(toString));

log('removeOneItem:', removeOneItem)
log('spreadTest:', spreadTest, sliceTest)
log('removeFive:', removeFive)

slice уже создает поверхностную копию массива, поэтому [...arr.slice(i)] не требуется.

...