Скажем, у меня есть функция:

function linesReverser(lines) {
  var localLines = lines.slice(); 
  localLines[1].reverse(); 
  return _.flatten(localLines);
}

И используя это так:

var input = [["Hello"],["Hello", "World"]["Attention", "Please"]];
var output1 = linesReverser(input); //["Hello", "World", "Hello", "Attention", "Please"]
var output2 = linesReverser(input); //["Hello", "Hello", "World", "Attention", "Please"]

Обратите внимание, как ссылка на объект является общим. Я новичок в JS, но я думал, что копирование значений уменьшит эту проблему (line.slice()), но, похоже, это не работает. Это из-за вложенных массивов?

Как я могу неразрушающим / неизменным образом выполнить обратное?

14
Dominic Bou-Samra 22 Янв 2013 в 05:33

3 ответа

Лучший ответ

Вы делаете мелкую копию массива lines. Чтобы скопировать вложенные массивы, вам нужно нарезать каждый из них.

var localLines = lines.map(function(arr) {
    return arr.slice();
});

Метод .map вернет новый массив возвращаемых значений, которые являются срезом каждого вложенного массива.


FWIW, вот более короткая версия, которая будет работать в современных браузерах, хотя я бы, вероятно, остановился на первой.

var localLines = lines.map(Array.apply.bind(Array, null));
5
the system 22 Янв 2013 в 01:43

Неразрушающий подход к обращению массива в Javascript

< Сильный > ES6

var array = [1,2,3];
array.reduce((ary, ele) => {ary.unshift(ele); return ary}, []);
// => [3,2,1];
// array => [1,2,3];

< Сильный > ES5

array.reduce(function(obj, ele){
  obj.unshift(ele);
  return obj;
},[]);
2
SoEzPz 21 Сен 2017 в 22:01

Также с помощью оператора распространения ES6:

const arr1 = [1,2,3];
const arr2 = [...arr1].reverse();
// arr1 => [1,2,3]
// arr2 => [3,2,1]
0
Ryan King 13 Фев 2020 в 17:20