5

UPDATE:

Many asked why not using [arr[0], arr[1]]. The problem is I have to pass this array to a method, which I don't have access Angular Material Table. And I don't want to call the method over and over again.

I already processed the arr array and I don't want to process pointer array to reflect the new data, which I already know where it is.

The Nina Scholz answer seems to solve the problem.


Is there a way to use "pointers" like C in Javascript?

What I want to do is:

I have an array with objects

const arr = [
    {prop: 3},
    {prop: 4},
];

And I want to have an array to point to the positions of this array

const pointer = [arr[0], arr[1]]; // I want pointer to point to be an array containing the first and second elements of arr

This will get a reference to the {prop: 3} and {prop: 4} objects, which is not what I want, because, if I do:

arr.splice(0, 0, {prop: 1}); // arr => [{prop:1},{prop:3},{prop:4}]
console.log(pointer); // [{prop: 3},{prop: 4}]

As you can see, pointer holds a reference to the objects {prop:3} and {prop:4}.

How can I achieve pointer to hold reference to the position 0 of the array, instead of the object stored in it? So, on this example, pointer => [{prop:1},{prop:3}]?

I can't call pointer = [arr[0], arr[1]] all the time because arr will change constantly and asynchronously.

Is there a "reactive" way to handle arrays?

Gustavo Lopes
  • 3,794
  • 4
  • 17
  • 57

3 Answers3

5

If your pointers are always to the same array, you can simply store the indexes.

const pointer = [0, 1];

Then you would use:

console.log(pointer.map(ptr => arr[ptr]));

If your pointers can point to different arrays, you can make the elements of pointer be objects that contain references to the array along with their indexes.

const pointer = [{a: arr, i: 0}, {a: arr1, i: 1}];
console.log(pointer.map(({a, i}) => a[i]));

Interesting aside: several decades ago I used a C implementation for Symbolics Lisp Machines. This is basically how it represented C pointers.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I updated my question. Even though I can hold the indexes, I still have to call the method again. I actually was looking for a `getter` inside the array, but I didn't know that :x Anyway, this is an excellent way to `point` to an array position, instead of a value. – Gustavo Lopes Dec 31 '18 at 21:00
4

You could use a getter function and return the element of the actual object.

const arr = [{ prop: 3 }, { prop: 4 }];
const pointer = [];

Object.defineProperty(pointer, 0, { get() { return arr[0]; } });
Object.defineProperty(pointer, 1, { get() { return arr[1]; } });

arr.splice(0, 0, { prop: 1 });
console.log(pointer);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you for your answer. It looks like what I was looking for. Another question, Is there a more straightforward way to create a `getter` inside an array? Or do I have to use the `Object` reflection to achieve this? – Gustavo Lopes Dec 31 '18 at 21:06
  • 1
    you need either `defineProperty` for a single property or `defineProperties` for more than one. ther is no workaround without, because every object would just be the object in the array, not a meta function. – Nina Scholz Dec 31 '18 at 21:10
1

You can use a Proxy (not supported by IE) with a get trap:

const arr = [{ prop: 3 }, { prop: 4 }];

const pointer = new Proxy([], {
  get(target, prop, receiver) {
    // if the prop is a string that can be converted to a number
    // return the corresponding value from the arr
    if(typeof prop === 'string' && !isNaN(Number(prop))) return arr[target[prop]];

    return Reflect.get(target, prop, receiver);
  }
});

pointer.push(0, 1);
console.log(pointer);

arr.splice(0, 0, { prop: 1 });
console.log(pointer);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209