创建子阵列的所有文档我已经看过slice
,它创建了一个数组的副本。我想知道是否可以在不复制的情况下创建数组切片,因此修改切片会修改原始数组。例如:
var foo = [1, 2, 3, 4, 5];
var bar = foo.subarray(2, 4);
console.log(bar); // [2, 3, 4]
bar[0] = 'hello, world';
console.log(bar); // ['hello, world', 3, 4]
console.log(foo); // [1, 'hello, world', 3, 4, 5]
答案 0 :(得分:5)
不幸的是,@ Derek的答案需要O(n)
来创建一个长度为n
的子数组,而如果我们使用{{1}访问值,我们可以在O(1)
中执行此操作而不是subarray.get(i)
:
subarry[i]
您可以使用它:
function make_subarray (array, from, to) {
return {
get: function (i) {
return array[i+from]
},
length: to - from
}
}
或者您可以在for (var i=0; i<subarray.length; i++) {
subarray.get(i)
}
定义中添加map()
函数:
subarray
现代浏览器对Derek的答案中每次拨打function make_subarray (array, from, to) {
return {
...
map: function (f) {
for (var i=0; i<this.length; i++)
f(this.get(i))
}
...
}
}
的速度都很慢,因此避免做很多事情会很好。
答案 1 :(得分:4)
此代码模拟与其他语言一样的引用(指针):
Array.prototype.subarray = function(i, j){
var self = this, arr = [];
for(var n = 0;i <= j; i++, n++){
(function(i){
Object.defineProperty(arr, n, { //Array is an Object
get: function(){
return self[i];
},
set: function(value){
self[i] = value;
return value;
}
});
})(i);
}
return arr;
}
//This is the exact code you have in your question
var foo = [1, 2, 3, 4, 5];
var bar = foo.subarray(2, 4);
console.log(bar); // [3, 4, 5]
bar[0] = 'hello, world'; // some magic happens here
console.log(bar); // ['hello, world', 4, 5]
console.log(foo); // [1, 2, 'hello, world', 4, 5]
演示:http://jsfiddle.net/DerekL/y7z9T/
subarray
不会通过复制原始数组来创建新数组;它会创建一个包含自定义getters的空白数组。要记住的一点是,新数组中的值链接到原始数组中的索引,而不是其内存位置。
index
0 1 2 3 4
┌────────────┐
┌───┬───┬┤───┬───┬───┐│
│ 1 │ 2 ││ 3 │ 4 │ 5 ││
└───┴───┴┤───┴───┴───┘│
└────────────┘
├──── Whole Array ────┤
├─ SubArray ─┤
“子数组”为原始数组提供“窗口”。您可以像通常那样更改和获取两个数组中的包含值。改变其中任何一个都会影响两者。但是,如果你试图将新元素推入“子数组”,那么就会发生不好的事情,所以不要这样做。
有关defineProperty
的更多信息,请visit MDN。
答案 2 :(得分:0)
我不认为,这是可能的,因为整数是一个简单的数据类型,如果你在一个对象中说它,我认为这是可能的。
这是一个有效的演示:
function co(value)
{
var obj = new Object();
obj.data = value;
obj.setValue = function(value)
{
this.data = value;
}
return obj;
}
var foo = [co(1), co(2), co(3), co(4), co(5)];
var bar = foo.slice(2, 4);
console.log(bar);
console.log(foo);
bar[0].setValue('hello, world');
console.log(bar);
console.log(foo);