不使用reverse方法反转数组问题(Eloquent JavaScript习题)
为什么用map+pop/push反转数组只得到部分结果?
问题原因
你遇到的问题核心在于**map()的遍历逻辑和pop()修改原数组的特性冲突**:
map()是基于调用它时数组的初始长度和索引来遍历的,不会因为遍历过程中原数组被修改而调整遍历次数。pop()会直接修改原数组,移除最后一个元素并返回它,同时原数组的长度会减1。
拿你的例子拆解:
初始数组是[1,2,3,4,5],map()本来要遍历5次(对应索引0-4):
- 第一次迭代(索引0):执行
array.pop(),取出5,原数组变成[1,2,3,4](长度4),newArray现在是[5] - 第二次迭代(索引1):执行
array.pop(),取出4,原数组变成[1,2,3](长度3),newArray现在是[5,4] - 第三次迭代(索引2):执行
array.pop(),取出3,原数组变成[1,2](长度2),newArray现在是[5,4,3] - 第四次迭代要访问索引3,但此时原数组长度只有2,索引3不存在,
map()直接停止遍历,不会继续执行后续的迭代。
这就是为什么你只得到了[5,4,3]而不是完整的反转数组。
符合要求的解决方案(无显式循环、不用reverse())
如果你不想用for/while这类显式循环,也不能用reverse(),可以试试这些方法:
方法1:使用reduceRight(推荐)
先复制原数组避免修改原数据,再从数组末尾开始遍历构建新数组:
function reverseArray(array) { return [...array].reduceRight((result, current) => { result.push(current); return result; }, []); }
或者用slice()复制数组(兼容更老的JS环境):
function reverseArray(array) { return array.slice().reduceRight((result, current) => { result.push(current); return result; }, []); }
方法2:使用reduce+unshift
从左到右遍历原数组,每次把元素插入新数组的开头:
function reverseArray(array) { return [...array].reduce((result, current) => { result.unshift(current); return result; }, []); }
内容的提问来源于stack exchange,提问作者Kat
相关产品推荐
相关产品推荐

