Search code examples
javascriptarraysjavascript-objects

How to set the value of the elements of the array to their position in the array in JavaScript


I have an array of objects such as:

let array = [{ position:0 },{ position:1 },{ position:2 }]

I wish that each object should store it's own position and update it when it's position is changed.

I'm using - array.splice(); to delete an object and then using this loop to calculate their positions again -

for(let i = 0, length1 = array.length; i < length1; i++){ array[i].position=i; }

But I want this to be done automatically without the loop Is there any way to achieve this in js.


Solution

  • ....and update it when it's position is changed

    That's the tricky bit, you'd either need to wrap a Proxy around the array and update the positions when things change:

    let array = [{position: 0},{position: 1},{position: 2}];
    function updateIndexes(array) {
        array.forEach((entry, index) => {
            entry.position = index;
        });
    }
    let parray = new Proxy(array, {
        defineProperty(target, key, descriptor) {
            const result = Reflect.defineProperty(target, key, descriptor);
            updateIndexes(target);
            return result;
        },
        set(target, key, value) {
            const result = Reflect.set(target, key, value);
            updateIndexes(target);
            return result;
        }
    });
    
    let second = parray[1];
    console.log(second.position); // 1
    parray.splice(0, 1);
    console.log(second.position); // 0

    ...or make the position an accessor property that searches for the object in the array and returns its current position, which means creating the accessor where it closes over the array:

    let array = [
        {
            get position() {
                return array.indexOf(this);
            }
        },
        {
            get position() {
                return array.indexOf(this);
            }
        },
        {
            get position() {
                return array.indexOf(this);
            }
        }
    ];
    
    let second = array[1];
    console.log(second.position); // 1
    array.splice(0, 1);
    console.log(second.position); // 0