有没有一种方法可以在 JavaScript 中返回数组的其余部分,即由数组的第一个元素以外的所有元素组成的数组部分?
注意:我不要求返回一个新数组,例如使用 arr.slice(1)
等,我不想砍掉数组的第一个元素,例如使用 arr.shift()
。
例如,给定数组 [3, 5, 8]
数组的其余部分是 [5, 8]
并且如果数组的其余部分发生更改,例如通过赋值(破坏性操作),数组也会发生变化。我刚刚发现,作为一个测试,证明其余部分是数组的其余部分,而不是由数组的其余元素组成的新数组。
注意:下面的代码示例是描述我想要什么,而不是具体描述我想做什么(即不是我想执行的操作)。我想做的是在底部的every
算法中。
var arr = [3, 5, 8];
var rest = rest(arr); // rest is [5, 8]
rest.push(13); // rest is [5, 8, 13] and hence the arr is [3, 5, 8, 13]
一个我可能需要这个的例子,我希望它遵循算法和我正在写的许多其他算法 GitHub organization , 在这两个中我总是使用 arr.slice(1)
:
function every(lst, f) {
if (lst.length === 0) {
return false;
} else {
if (f(lst[0]) === true) {
return every(lst.slice(1), f);
} else {
return false;
}
}
}
我认为用我要求的而不是 arr.slice(1)
将保持此类算法的内存使用并保留我想要采用的递归函数风格。
最佳答案
不,这通常是不可能的。普通数组没有“ View ”或“指针”1。
您可以使用 Proxy
伪造它,但我怀疑这是个好主意。
1:在 typed arrays 上执行此操作很简单(它们是后备缓冲区上的 View ),但请注意您不能推送
给它们。
I possibly need this and I would want to have it for recursive-functional style algorithms where I currently use
arr.slice(1)
but would prefer to keep memory usage low
实际上,所有这些实现的内存使用率都很低——它们分配的内存不会比输入多。不过,重复调用 slice(1)
确实会给垃圾收集器带来高压力。
如果你正在寻找更高的效率,我会推荐
- 避免递归。 JS 引擎仍然没有实现尾递归,所以递归并不便宜。
- 不传递数组(的新副本)。简单地传递一个开始的索引,例如通过使用关闭数组参数并访问
array[i]
而不是array[0]
的内部递归函数。有关示例,请参阅@Pointy 的更新答案。
如果您正在寻找更实用的样式,我建议您使用 folds . (在 JavaScript 中也称为 reduce
,但如果你想偷懒,可能需要自己动手)。根据 fold
实现您的算法,然后很容易将 fold
实现替换为更高效(例如迭代)的实现。
最后但同样重要的是,为了在保持递归风格的同时提高效率,您可以使用 iterators .它们的界面可能看起来不是特别实用,但如果您坚持,您可以轻松地创建一个不可变的包装器,它可以延迟生成一个链表。
关于javascript - 有没有办法返回 JavaScript 数组的其余部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54378798/