Я хочу перевернуть массив на месте без использования обратного метода. Я попробовал следующий код:
function reverseArray(arr) {
return arr.map(() => {
return arr.pop()
})
}
console.info(reverseArray([1, 2, 3, 4]));
//logs [4,3,undefined,undefined]
Используя отладчик инструментов разработчика, это то, что регистрируется в консоли: (4) [4, 3, empty × 2]
.
arr.pop()
возвращает неопределенное значение, если вызывается для пустого массива, но, насколько я понимаю, в этом случае он не должен быть пустым.
Вопрос: что происходит? Почему первые два элемента печатаются правильно, а остальные нет?
Для массивов уже есть обратный метод. Зачем изобретать велосипед?
return arr[ arr.length - 1 - i ];
должен сделать работу
@Taplar Вопрос конкретно в том, чтобы не использовать этот метод.
Я понимаю. Если это для обучения, круто. В противном случае это просто пустая трата времени.
Вы не должны использовать map()
, если хотите, чтобы результат был в исходном массиве. Он всегда возвращает новый массив.
Проблема в том, что вы pop
некоторые элементы и, следовательно, они больше не существуют в массиве. Итак, первые два элемента отмечены pop
, а два других записаны в этих местах, но внутренне они тем временем больше не существуют.
Есть также много других (лучших) решений, подобных этому (из здесь):
function reverse (array) {
var i = 0,
n = array.length,
middle = Math.floor(n / 2),
temp = null;
for (; i < middle; i += 1) {
temp = array[i];
array[i] = array[n - 1 - i];
array[n - 1 - i] = temp;
}
}
Вы удаляете элементы из массива, пока перебираете его. В документации говорится:
Диапазон элементов, обрабатываемых картой, устанавливается перед первым вызовом обратного вызова. ... Элементы, которые удаляются после начала вызова карты и до посещения, не посещаются.
Итак, map()
определяет в начале, что он будет повторяться 4 раза, создавая массив из 4 элементов.
На первой итерации arr.pop()
удаляет arr[3]
. На второй итерации он удаляет arr[2]
.
Третья итерация ожидает обработки arr[2]
. Но поскольку этот элемент больше не существует, он не вызывает функцию обратного вызова, а просто сохраняет undefined
в массиве результатов. То же самое происходит и на четвертой итерации.
Вы можете перебрать копию массива.
function reverseArray(arr) {
return [...arr].map(() => {
return arr.pop()
})
}
console.info(reverseArray([1, 2, 3, 4]));
Проблема с этим решением в том, что оно не на месте, как запрошено
Исходный код тоже не на месте. map()
всегда создает новый массив.
Хотя это правда, вопрос требовал решения на месте. Вот почему мне было интересно
Вы удаляете элементы из массива, пока перебираете его.