0

Is there any way to replicate Python's array indexing system in JavaScript.

To access the last element in JavaScript, I would need to do this:

last = arr[arr.length - 1]
secondLast = arr[arr.length - 2]

Is there any way I could access the elements using Python's way, eg:

last = arr[-1]
secondLast = arr[-2]

This gets really annoying when you have an array of arrays.

arr = [[1, 2], [3, 4], [5, 6]]

// In JavaScript, to get 6:
lastJS = arr[arr.length - 1][arr[arr.length - 1].length - 1]

# In Python, simple:
lastPy = arr[-1][-1]

Any ideas? All I have seen online only allows arr.last or arr.last() by using Array.prototype.

4 Answers4

1

No. JavaScript does not support operator overloading. However, you can implement a method yourself that supports Python's index handling.

Edit: I suppose you can recreate that effect using Proxy (in ES6+), but I would not recommend it: https://jsfiddle.net/DerekL/Lfjznnbb/

class PythonArray {
    constructor() {
        return new Proxy([], {
            get: function(target, name) {
                var index = parseInt(name, 10);

                if (name === NaN) {
                    if (name in target) return target[name];
                    else throw "Not a number";
                }

                // simple implementation
                if(index < 0)   return target[target.length + index];
                else    return target[index];
            }
        });
    }

    static from(arr){
        var pythonArray = new PythonArray();
        for(var i = 0; i < arr.length; i++){
            pythonArray[i] = arr[i];
        }
        return pythonArray;
    }
}

var arr = PythonArray.from([1, 2, 3]);
console.log(arr[0]);         // 1
console.log(arr[-1]);        // 3
console.log(arr.join("|"));  // still works
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • Is there any way to implement the method? I tried using Array.prototype to no success. Assuming that arrays are just objects, I suspect arr[-1] should be a valid syntax given some modification. – Michael Nov 06 '17 at 07:15
  • You technically can do this: https://jsfiddle.net/DerekL/Lfjznnbb/, but please do not use it in any production code! – Derek 朕會功夫 Nov 06 '17 at 07:24
0

You can try the following using Object.defineProperty

Object.defineProperty(Array.prototype, "-1", {
  get : function(index){ return this[this.length - 1] ) }
});

This will return the last value for -1, however I don't think a generic one can be defined.

Demo

var arr = ["A", "B", "C"];
console.log( "Before " , arr[ -1 ] );
Object.defineProperty(Array.prototype, "-1", {
  get : function(index){ return this[this.length - 1]; }
});
console.log( "After " ,  arr[ -1 ] );

Similarly, you can define a property for other negative indexes.

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

Arrays are objects as well.

let arrayObj = []
arrayObj[-1] = "I exist";
console.log(arrayObj) // [ '-1': 'I exist' ]

Hence using array[-1] is not a good idea for the last index;

Instead just add an Prototype function getFromLast() that would let you access the elements from the last of your array

Array.prototype.getFromLast = function(index) {
    return this[this.length-index-1];
}
a = [1,23,123,4,1,1231,12]
a.getFromLast(3) // 4
Prasanna
  • 4,125
  • 18
  • 41
  • I read that modifying Array.prototype is generally a bad practice. Will it be in this case? – Michael Nov 06 '17 at 07:34
  • There is no danger if you want this for yourself and not using it in any shippable product. Products you ship may be used in different environments and functions added can sometimes match with something similar used by others. Read this for more information https://stackoverflow.com/questions/8859828/javascript-what-dangers-are-in-extending-array-prototype – Prasanna Nov 06 '17 at 07:37
  • Modifying native prototypes is generally a bad practice. Just look at the mess Prototype.js has created. – Derek 朕會功夫 Nov 06 '17 at 07:44
-1

You could achieve that by creating a function like this:

var some_array = ["name", "game", "fame"];

function getElement(array, index) {
  return (array[array.length + (index)]);
};

console.log(getElement(some_array, -1));
Karan Dhir
  • 731
  • 1
  • 6
  • 24