Nate
Nate

Reputation: 7856

Splice item of array and of all its references (children array)

I would like to know if it's possible to slice (or delete an item) of an array and transmit this change to its children. Its children having only part of the items of the parent.

Meaning, I have:

let myArr = [{number: 1}, {number: 2}, {number: 3}, {number: 4}];
let partRef = [];

for(let int = 0; int < myArr.length - 1; int++){
    partRef.push(myArr[int]);
}
// delete here item 2 from myArr and it gets transmitted to partRef

What I would like is that when I myArr.splice(1, 1) (or any delete function), the number 2 also disappears from partRef.

The following plunker shows the real case with Angular 2 and its classes (everything happens in class1 and class2). You have to open your console to see.

Upvotes: 1

Views: 487

Answers (1)

trincot
trincot

Reputation: 350137

As the partRef is a different array, distinct from myArr, this is not possible. But read on...

In JavaScript there are some ways to have views on the same memory location, using ArrayBuffer, but it seems not possible to use that as solution in this context.

I will propose the use of a proxy to achieve the effect. The idea is that you trap any myArr.splice call and apply it equally to the partRef array.

But first I should note that the loop you have really comes down to:

let partRef = myArr.slice(0, 3);

Here is the proxy-based solution:

let myArr = [{number: 1}, {number: 2}, {number: 3}, {number: 4}];
let partRef = myArr.slice(0, 3);

// Our custom version of `splice`. It does the normal `splice`, but
// also performs it on `partRef`:
function mySplice () {
    [].splice.apply(partRef, arguments);
    return [].splice.apply(this, arguments);
}

// Redefine `myArr` as a proxy on itself, and trap any call to `splice`
myArr = new Proxy(myArr, {
    get: function (obj, prop) {
        // If `splice` is accessed, then use `mySplice` instead. All other
        // properties are not influenced.
        return (prop === 'splice') ? mySplice : obj[prop];
    }
});

// Test it.
myArr.splice(1, 1);
console.log(partRef);

The nice thing about such a "proxied" object is that cannot (easily) be distinguished from the original. For instance Array.isArray(myArr) will return true.

Upvotes: 3

Related Questions