2012-03-01 4 views
3

Как получить ссылку на кусочек массива?Ссылка на срез массива

var A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']; 
A.mySlice = function(l, h){return this.slice(l,h)}; 

var B = A.mySlice(1,5); // ["b", "c", "d", "e"] 

Он работает для прямых фрагментов, полученных от A. Но как получить его для всех полученных фрагментов? (В этом случае для B)

B.mySlice = function(l, h){return this.slice(l,h)}; 

A[3] = 33; 
A.mySlice(1,5) // ["b", "c", 33, "e"] => ok 
B.mySlice(0,3) // ["b", "c", "d"] => I would want ["b", "c", 33] 
+0

Я не думаю, что это возможно, но я хотел бы посмотреть, что другие придумали, –

ответ

2

Я не думаю, что вы можете сделать это с помощью родных массивов JS (ну, в любом случае, не так просто).

Я думаю, что самый чистый подход будет возвращаться и использовать пользовательские объекты для представления срезов. Возможно, что-то вдоль этих линий:

function ArraySlice(arr, lo, hi){ 
    this.arr = arr; 
    this.lo = lo; 
    this.hi = hi; 
    this.length = hi - lo; 
}; 
ArraySlice.prototype._contains = function(ix){ 
    return this.lo + ix < this.hi; 
}; 
ArraySlice.prototype.get = function(ix){ 
    if (this._contains(ix)){ 
     return this.arr[this.lo + ix]; 
    }else{ 
     return; //undefined 
    } 
}; 
ArraySlice.prototype.set = function(ix, value){ 
    if (this._contains(ix)){ 
     return (this.arr[this.lo + ix] = value); 
    }else{ 
     return; //undefined 
    } 
}; 

var a = [0,1,2,3,4,5]; 
var b = new ArraySlice(a, 1, 3); 

a[2] = 17; 
console.log(b.get(1)); 

Конечно, это теряет удобный [] синтаксис и объекты не массивы больше, но подклассы массив раздражает и подвержен ошибкам, и я не считаю, что это кросс-браузер способ перегрузки оператора.

+0

Удивительное прозвище удивительно –

+0

@Truth: Спасибо. Возьмите эти 128 кусочков конфет за ваши проблемы. – hugomg

+0

Конфеты? Я хочу Мастер Шары! : D –

3

slice() копирует элементы в новый массив.

Итак, в вашем примере A и B - это два совершенно разных массива. Таким образом, изменение элементов в одном не влияет на другое.

0

Вот единственное возможное решение, которое я вижу:

  • расширить класс Array, и хранить все данные массива в классе одноплодной например
  • создать уникальный идентификатор (UID), когда вы сначала создать новый массив
  • использовать этот идентификатор, когда вы пытаетесь получить данные из одноэлементных использования
  • тот же идентификатор, когда вы делаете срез

Это может, однако, ломать много вашего кода.

0

Я уверен, что это невозможно в Javascript. Эта строка var B = A.mySlice(1,5); устанавливает B в объект массива, содержащий срез чисел A. Он не имеет ссылки на A. Это всего лишь объект массива.

0

Это не совсем чист, так как вы иметь дело с объектами функции, но вы можете обернуть вызовы цепи резервной копии исходного массива с помощью затворов:

var A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']; 
A.mySlice = function (l, h) { return function() { return this.slice(l, h); }; }; 

var B = A.mySlice(1, 5); // B() will resolve to ["b", "c", "d", "e"] 
B.mySlice = function (l, h) { return function() { return this().slice(1, h) }; }; 

A[3] = 33; 
A.mySlice(1, 5)() // ["b", "c", 33, "e"] 
B.mySlice(0, 3)() // ["b", "c", 33] 
Смежные вопросы