Can we use list in JavaScript?

Getting the last element of a list/array is a common operation. In this tutorial, we'll take a look at how to get the last element in a JavaScript array/list.

JavaScript is a weakly-typed or untyped language, which means that the type of variable doesn't need to be declared before using it, since JavaScript determines the type by reading the variable's value.

var x = "something" is evaluated, and x is assigned to a String type. The same process applies to lists - you don't need to define a list's type, you can just fill the list up with values.

A list is defined by putting the elements in between the square brackets ([]), where the elements can be heterogenous (don't have to be of the same type):

var myList = ["Peter", "Smith", 25, 23, "Random String", 10]

JavaScript has a lot of built-in methods that can be used to manipulate lists like this one. Here are the ones we'll be using to get the last element.

Get Last Element Using length

The length attribute of a list denotes the number of elements in a list:

console.log(myList.length)

Element indexing in arrays/lists in JavaScript is much akin to other languages. We can access an element, based on its index, by passing it in square brackets [], referencing the array. The last element has the index of length-1.

Since the length field just returns the saved value of elements - this is a fast, efficient and cheap operation. The best way to get the last element of a JavaScript array/list is:

var lastElement = myList[myList.length - 1]; console.log(lastElement);

This results in:

10

Get Last Element Using pop()

The pop() method returns the last element of a collection, but removes it during the process. Though, if we use the spread operator from ES6 - we can avoid this functionality by temporarily copying the list in memory, and performing pop() on the copy, keeping the original list intact.

The pop() Method

Let's pop() the last element off the list:

var lastElement = myList.pop(); console.log(lastElement) console.log(myList)

This results in the list being cut short of that element:

10 ["Peter", "Smith", 25, 23, "Random String"]

If you don't need the original list to stay intact, than you can pop elements off of it, but if you do need the original, you can make a copy and pop() from it.

pop() with ES6' Spread Operator

ES6 is short for EcmaScript6, which is a JavaScript standard used to make programming in JavaScript easier (to code less, but do more).

It was founded back in 1997 and it's first major breakthrough was in 2015, with the ES6 standard (or EcmaScript2015). The latest version is the 11th one, developed in 2020. All versions are meant to make coding easier in JavaScript (with new syntax rules, new keywords, etc.).

The feature that we can leverage here is the spread operator (...).

Amongst other features, the spread operator can copy lists/arrays:

[...myList]

This generates a new list, with the same elements as myList. That being said - we can pop() from the new list instead of the original one:

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

console.log([...myList].pop()) console.log(myList)

This results in:

10 ["Peter", "Smith", 25, 23, "Random String", 10]

Note: This may be convinient to write, but is not the cheapest of solutions, since it copies a list. For small lists, it doesn't reduce the performance by much, but with longers lists, this is an unefficient way to simply get the last element.

Get Last Element Using slice()

The slice(a, b) method 'slices' the array from point a to point b-1 - given that a and b are integers. In a more mathematical way, you can look at slice like this: [a, b) - the element at a is included, whilst the element at b is not:

console.log(myList.slice(1, 4))

This results in a slice of the original array:

["Smith", 25, 23]

The slice() method also accepts negative indexing - where it iterates through the collection backwards. So if we slice(-4, -1), the iteration will start from the third element from the back and end at one before the last one (because slice doesn't include the b point).

This allows us to simply include one last element, from the end of the list via slice():

console.log(myList.slice(-1))

Which results in:

[10]

This is still an array, so to get this element we access it with myList.slice(-1)[0] - which will return our element:

console.log(myList.slice(-1)[0])

Note: slice() is best used when you want to retrieve the last N elements of an array, rather than one, since you can simply use length-1 instead.

Get Last Element Using reverse()

The reverse() method reverses the list in-place. The last element will become the first, and vice-versa:

console.log(myList.reverse())

The output will be:

[10, 'Random String', 23, 25, 'Smith', 'Peter']

Now our element is the first one, so we can access it with myListReversed[0].

Note: Reversing an array/list is also a potentially very expensive operation. Avoid reversing the collection if the only thing you want to do is access the last element. If you are to reverse it anyway - you can access the element like this. If not, refer to the first approach of using length-1.

Conclusion

The cheapest, most efficient, and probably most intuitive method of these is the first - myList[myList.length()-1]. This is what you'll be using most of the time.

Using pop() removes the element from the list and returns it. If you want to remove the element - this is the approach you'll want to be using, since otherwise, you'll have to remove the element manually.

slice() gives us a slice, which is a great aproach if we want to get the last N elements.

reverse() reverses the array in-place and should be avoided if you just want to get an element. If you're reversing the array anyway, though, this doesn't cost anything extra.

An ordered list of values.

A List is backed by a doubly linked list with a head node.

The list has a head property to an empty node. The list begins with the next node from the head. The last node of the list is the prev node from the head. The head represents the node one past the end of the list and has no value.

Nodes can be manipulated directly. Lists use a Node(value) property as their node constructor. It supports delete(), addBefore(node), and addAfter(node). Directly manipulating next and prev of a node allows for fast splicing.

Nodes can be reused to avoid garbage collector churn. However, if you do not need to splice, a Deque may perform better than List.

Lists can be iterated. The iterator will produce artificial indexes for each value.

Lists provide slow random access by index. Methods that accept indexes to seek a position will count as they walk to the sought node. These methods will always accept a node instead to instantly traverse to a known position.

Lists provide range change listeners, but at significant cost. Making range changes observable on a list requires that for each change to the list, it must scan back to the head of the list to determine the node’s index, which obviates the principle advantage of using the linked list structure. Also, direct manipulation of the nodes is not observable and will require manual change dispatch.

length

The number of items in this collection.

push(...values)

Adds values to the end of a collection.

pop()

Removes a value from the end of a collection, and returns that value.

shift()

Removes a value from the beginning of a collection, and returns that value.

unshift(...values)

Adds values to the beginning of a collection.

peek()

Returns the value at the beginning of a collection, the value that would be returned by shift().

poke(value)

Replaces the value at the beginning of a collection, the value that would be returned by shift().

has(value)

Whether an equivalent value exists in this collection.

has(value, equals?)

Returns whether an equivalent value exists in this collection.

get(value)

Retrieves the equivalent value from the collection.

get(value, equals?)

Retrieves the equivalent value from this collection.

add(value)

Adds a value to a collection.

delete(value)

Deletes the first equivalent value. Returns whether the key was found and successfully deleted.

delete(value, equals?)

Seeks out and deletes an equivalent value. Returns whether the value was found and successfully deleted.

addEach(values|map)

Copies values or entries from another collection into this collection, and then returns this.

deleteEach(values|keys, equals?)

Deletes every value or every value for each key. Returns the number of successful deletions.

deleteAll(value, equals?)

Deletes every value equivalent to the given value from the collection.

slice(start?, end?)

Returns an array of the values contained in the half-open interval [start, end), that is, including the start and excluding the end.

splice(start, length, ...values)

Replaces a length of values from a starting position with the given variadic values, and returns the values that were replaced as an array.

swap(start, length, values?)

Replaces a length of values from a starting position with the given values.

clear()

Deletes all of the values in the collection.

find(value, equals?, start?)

Finds the first equivalent value.

findValue(value, equals?, start?)

Finds the first equivalent value.

findLast(value, equals?, start?)

Finds the last equivalent value, searching from the right.

findLastValue(value, equals?, start?)

Finds the last equivalent value, searching from the right.

iterate|iterator()

Iterates every value in this collection.

forEach(callback, thisp?)

Calls the callback for each entry in the collection.

map(callback, thisp?)

Returns an array of the respective return values of a callback for each entry in this collection.

filter(callback, thisp?)

Returns an array with each value from this collection that passes the given test.

reduce(callback, basis)

Aggregates every value in this collection with the result collected up to that index.

reduceRight(callback, basis)

Aggregates every value in this collection, from right to left.

group(callback, thisp?, equals?)

Returns an array of [key, class] entries where every value from the collection is placed into the same equivalence class if they return the same key through the given callback.

some(callback, thisp?)

Returns whether any entry in this collection passes a given test.

every(callback, thisp?)

Returns whether every entry in this collection passes a given test.

any()

Returns whether any value in the collection is truthy.

all()

Returns whether all values in the collection are truthy.

one()

Returns one, arbitrary value from this collection, or undefined if there are none.

only()

Returns the only value in this collection, or undefined if there is more than one value, or if there are no values in the collection.

sort(compare?)

Sorts a collection in place.

sorted(compare?)

Returns a sorted array of the values in this collection.

reverse()

Reverses the order of this collection in place.

reversed()

Returns a copy of this collection with the values in reverse order.

join(delimiter?)

Returns a string of all the values in the collection delimited by the given string.

sum(zero?)

Returns the sum of all values in this collection.

average()

Returns the arithmetic mean of the collection, by computing its sum and the count of values and returning the quotient.

min()

Returns the smallest value in this collection.

max()

Returns the largest value in this collection.

zip(...iterables)

Returns an array of the respective values in this collection and in each collection provided as an argument.

enumerate(start?)

Returns an array of [index, value] entries for each value in this collection, counting all values from the given index.

concat(...iterables)

Returns a new collection of the same type containing all the values of itself and the values of any number of other iterable collections in order.

flatten()

Assuming that this is a collection of collections, returns a new collection that contains all the values of each nested collection in order.

toArray()

Returns an array of each value in this collection.

toObject()

Returns an object with each property name and value corresponding to the entries in this collection.

toJSON()

Used by JSON.stringify to create a JSON representation of the collection.

equals(value, equals?)

Returns whether this collection is equivalent to the given collection.

compare(value, compare?)

Compares two values and returns a number having the same relative value to zero.

clone(depth?, memo?)

Creates a deep replica of this collection.

constructClone(values?)

Creates a shallow clone of this collection.

scan(index, default)

An internal utility of List coercing indexes to nodes.

addRangeChangeListener(listener, token?, beforeChange?)

Adds a listener for when values are added or removed at any position.

removeRangeChangeListener(listener, token?, beforeChange?)

Unregisters a range change listener provided by addRangeChangeListener.

dispatchRangeChange(plus, minus, index, beforeChange?)

Informs range change listeners that values were removed then added at an index.

addBeforeRangeChangeListener(listener, token?)

Adds a listener for before values are added or removed at any position.

removeBeforeRangeChangeListener(listener, token?)

Unregisters a range change listener provided by addBeforeRangeChangeListener or addRangeChangeListener with the beforeChange flag.

dispatchBeforeRangeChange(plus, minus, index)

Informs range change listeners that values will be removed then added at an index.

addOwnPropertyChangeListener(key, listener, beforeChange?)

Adds a listener for an owned property with the given name.

addBeforeOwnPropertyChangeListener(name, listener)

Adds a listener for before a property changes.

removeOwnPropertyChangeListener(name, listener, beforeChange?)

Unregisters a property change listener provided by addOwnPropertyChangeListener.

removeBeforeOwnPropertyChangeListener(key, listener)

Unregisters a property change listener provided by addBeforeOwnPropertyChangeListener or addOwnPropertyChangeListener with the beforeChange flag.

dispatchOwnPropertyChange(key, value, beforeChange?)

Informs property change listeners that the value for a property name has changed.

dispatchBeforeOwnPropertyChange(key, value)

Informs property change listeners that the value for a property name will change.

makePropertyObservable(name)

May perform internal changes necessary to dispatch property changes for a particular name.

makeObservable()

Makes changes observable for this collection.