DEV Community

Cover image for Access array items using negative indices
Phuoc Nguyen
Phuoc Nguyen

Posted on • Originally published at phuoc.ng

Access array items using negative indices

In JavaScript, arrays are a great way to store multiple values in a single variable. Each value in an array has an index that represents its position within the array. The first element of an array is assigned an index of 0, the second element is assigned an index of 1, and so on.

To access a specific item in an array, you can use its corresponding index. For example, if you have an array called fruits that contains ["apple", "banana", "orange"], you can access the first item in the array by using fruits[0].

It's important to note that JavaScript arrays don't support negative indexing. Unfortunately, negative indexing isn't an option for accessing items at the end of an array without knowing its length.

Here's an example of how we would like it to work in JavaScript:

const fruits = ["apple", "banana", "orange"];

fruits[-1];     // `orange`
fruits[-2];     // `banana`
fruits[-3];     // `apple`
Enter fullscreen mode Exit fullscreen mode

The code above shows how to access array elements using negative indexes. In this example, we have an array called fruits with three items: "apple", "banana", and "orange".

To access the last item in the array using a negative index, we use -1. So fruits[-1] gets us "orange". Similarly, fruits[-2] gets us "banana", and fruits[-3] gets us "apple".

This is really helpful when you don't know how long an array is or if you want to access items from the end of an array without having to do any math to figure out their index.

Negative indexing in different programming languages

While JavaScript doesn't support negative indexing, other programming languages like Python, Ruby, and Lua do. Here are some examples of how negative indexing works in these languages:

  • In Python, negative indexing allows you to access elements from the end of an array. For instance, fruits[-1] would give you the last element of the fruits array.
  • In Ruby, negative indexes can also be used to access elements from the end of an array. For example, if you have an array called numbers that contains [1, 2, 3], you can get the last element by using numbers[-1].
  • Similarly, in Lua, negative indexes can be used to access elements from the end of a table. If you have a table called colors that contains { "red", "green", "blue" }, then colors[-2] would give you the second-to-last color in the table.

Negative indexing offers a convenient way to access elements at the end of arrays or tables without the need to know their length beforehand.

Implementing negative indexing in JavaScript arrays

If you're a JavaScript developer, you might be familiar with the frustration of not being able to access array elements from the end using negative indexes. But fear not, there's a simple solution! The withNegativeIndex function in the code block below demonstrates how to implement negative indexing for JavaScript arrays.

const withNegativeIndex = (arr) => {
    return new Proxy(arr, {
        get(target, property, receiver) {
            if (property < 0) {
                property = +property + target.length;
            }
            return Reflect.get(target, property, receiver);
        },
    });
};
Enter fullscreen mode Exit fullscreen mode

This function takes an array as input and returns a new proxy object. The proxy object is like a middleman that handles requests for array elements. When a request comes in, the proxy checks if the requested index is negative. If it is, the function adds the length of the array to the index to get the corresponding positive index.

We use +property instead of just property in this calculation because of type coercion in JavaScript. Take a look at the sample code below:

console.log("-2" + 3);      // "-23"
console.log(+"-2" + 3);     // 1
Enter fullscreen mode Exit fullscreen mode

By using +property, adding a number to a string automatically converts the string to a number. Without this conversion, we would end up concatenating strings instead of adding numbers.

When it comes to type coercion, there's no need to convert the property to a number before comparing it to 0.

"-2" < 0      // true
"2" < 0       // false
"0" < 0       // false

Let's say you have an array called fruits with three items: "apple", "banana", and "orange". You can use withNegativeIndex to access the last item in the array using -1.

const fruits = ["apple", "banana", "orange"];
const proxiedFruits = withNegativeIndex(fruits);

proxiedFruits[-1];      // `orange`
Enter fullscreen mode Exit fullscreen mode

In this example, we pass an array called fruits to the function withNegativeIndex, which returns a new object called proxiedFruits. When we try to access -1 on proxiedFruits, our custom code intercepts the request, calculates that -1 + 3 = 2, and returns "orange", which is at index 2 in fruits.

With this technique, you can easily access any element in an array using negative indices, without worrying about the length of the array or manually calculating its positive index.

Conclusion

When working with arrays in JavaScript, sometimes you need to access elements at the end of an array without knowing the length. That's where negative indexing comes in. It's a technique that's available in some programming languages like Python, Ruby, and Lua, but not in JavaScript by default. However, you can still use negative indexing in JavaScript with a custom function like withNegativeIndex.

By implementing negative indexing in your JavaScript code, you can make it more efficient and concise when working with arrays. So take the time to understand how it works and give it a try in your next project.


If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:

Top comments (1)

Collapse
 
morgboer profile image
Riaan Pietersen

Thanks for the post, Phuoc!
May I ask how this is more efficient than using arr.length-1, for example, to get the last element in an array? fruits[fruits.length-1] seems like a highly logical way of getting said last value if you don't know the length and you can then simply add -2, -3, etc to achieve the same thing?