FORUM Menu

Useful Array Tricks

by kirupa   |    filed under JS Tips and Tricks

When we scratch beyond the surface of what arrays are capable of, we enter into some unchartered territory - even if what we are doing seems very reasonable. In this short article, let's chart the unknown and look at how we would accomplish some common array-related tasks such as:

  1. Copying/Cloning an Array
  2. Checking if an Object Is an Array
  3. Deleting an Array Item
  4. Emptying an Array
  5. Making Your Array Items Unique
  6. Sorting Items
  7. Shuffling / Randomly Rearranging
  8. Picking a Random Item
  9. Merging Arrays
  10. Swapping Items
  11. Turning an Array into an Object
  12. Reversing our Array
  13. Checking if All Array Elements Pass a Test
  14. Checking if Some Array Elements Pass a Test
  15. TV/VCR Repair (and a degree from CGNU)

If any of these seem particularly interesting, click on the heading to check it out directly. If not, just read on for some totally-not-boring tricks about our friendly, neighborhood array.

Onwards!

Copying/Cloning an Array

If you want to copy or clone an array to a new variable, you will need to use the slice method without specifying any arguments:

let foo = ["fee", "fi", "fo", "fum"];
let fooCopy = foo.slice();

console.log(fooCopy);

In this example, fooCopy contains a full copy of all the items in the foo array.

Checking if an Object Is an Array

For detecting whether an item is an array or not, the hip way that all the cool kids (like senocular) use is Array.isArray:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(Array.isArray(numbers)); // true

If you are old-school, you can also check the constructor property on whatever array-like object to see if its value is an Array or not:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Array
console.log(numbers.constructor === Array);

let name = "Homer Simpson";

// Not an array
console.log(name.constructor === Array);

Notice that we are checking for the Array type directly as opposed to the string-based name for it.

Deleting an Array Item

While it is easy to add an item to the array, there is no built-in equivalent for removing an item you've added. You'll need to rely on indexOf and splice to create your own remove functionality:

let evenNumbers = [0, 2, 4, 6, 7, 8, 10];
console.log(evenNumbers.length) // 7 items

let removeIndex = evenNumbers.indexOf(7);

if (removeIndex > -1) {
    evenNumbers.splice(removeIndex, 1);
}

console.log(evenNumbers.length) // 6 items
console.log(evenNumbers);

This approach will completely remove any trace of the array item ever having existed.

For a less intrusive approach, you have the delete keyword. If you try to delete an item from an array using it, the behavior is a bit different. Take a look at the following code snippet to see what happens:

let evenNumbers = [0, 2, 4, 6, 7, 8, 10];
console.log(evenNumbers.length) // 7 items

let removeIndex = evenNumbers.indexOf(7);
delete evenNumbers[removeIndex];

console.log(evenNumbers.length) // 7 items
console.log(evenNumbers);

The only thing that happens using the delete keyword is that the removed item is set to an empty value, but an array entry still remains. That entry will now reference an empty item. The length of the items in the array is still the same as well. That may not be what you expect. If we inspect the output of the above code, here is what evenNumbers will print to our console:

[0, 2, 4, 6, empty, 8, 10]

Where our odd 7 number was, you will see empty instead. The takeaway is this. If you want to retain all of your array indexes, use the delete keyword when you want to remove an item. If you want to fully remove an item and any trace of it from your array, use the indexOf and splice approach instead.

Emptying an Array

To empty out and delete all the contents from your array, the simplest (and also the fastest-ish!) way is to use the totally nontinutive approach where you set the length property of your array to 0:

let myItems = ["apples", "oranges", "bananas", "kiwis"];
console.log(myItems.length); // 4

myItems.length = 0;
console.log(myItems.length); // 0

I know this looks absolutely ridiculous, but try it out for yourself. It totally works!

Making Your Array Items Unique

Thanks to ES6 and the Set object, removing duplicate values from your array is pretty straightforward:

let names = ["Peter", "Joe", "Cleveland", "Quagmire", "Joe"];
let uniqueNames = [...new Set(names)];

console.log(uniqueNames);

The trick is to use the spread (...) operator that expands a collection of items into its individual pieces. There is one wrinkle with this approach. In my testing, the performance of this approach is much slower than the more verbose approach described here. You can see for yourself by running the jsperf test.

Sorting Items

Arrays in JavaScript come with a handy built-in sort method that allows you to specify exactly how to sort. Take a look at the following example where we are sorting some numbers as well as text:

let numbers = [3, 10, 2, 14, 7, 2, 9, 5];
let beatles = ["Ringo", "George", "Paul", "John"];

numbers.sort(compareValues);
beatles.sort(compareValues);

function compareValues(a, b) {
    if (a < b) {
        // if a less than b
        return -1;
    } else if (a > b) {
        // if a greater than b
        return 1;
    } else {
        // a and b are equal
        return 0;
    }
}

console.log(numbers);
console.log(beatles);

We are using one comparison function called compareValues. This function (a callback function to be precise) compares two values that are passed in as an argument, and all we have to do is specify which of the two values should appear first. We do that by returning either -1, 1, or 0. Returning -1 means the first value will appear ahead of the second value. Returning 1 means the first value will appear after the second value. Returning 0 means both values are equal.

Our compareValues function is pretty straightforward. For more involved types of data, you'll need to customize your comparison function appropriately, but even that isn't rocket science. Below is an example of sorting an array of Objects:

let shows = [
{
    name: "Frasier",
    seasons: 11
},
{
    name: "Seinfeld",
    seasons: 9
},
{
    name: "Friends",
    seasons: 10
},
{
    name: "Cheers",
    seasons: 11
},
{
    name: "Animaniacs",
    seasons: 5
},
{
    name: "Everybody Loves Raymond",
    seasons: 9
}
];

function showComparison(a, b) {
    if (a.seasons < b.seasons) {
        // if a less than b
        return -1;
    } else if (a.seasons > b.seasons) {
        // if a greater than b
        return 1;
    } else {
        // a and b are equal
        return 0;
    }
}

let sortedShows = shows.sort(showComparison);
console.log(sortedShows);

In this example, we are sorting television shows by the number of seasons. Each television show is represented as an Object in our array. Notice how we have our showComparison function defined. Instead of comparing the two values directly, we are dotting in to the seasons value to help determine which show should appear first.

Shuffling / Randomly Rearranging

If you want to spice things up, you can randomly rearrange all the contents of our array. To do that, you can use the following shuffling code:

Array.prototype.shuffle = function () {
  let input = this;

  for (let i = input.length - 1; i >= 0; i--) {

    let randomIndex = Math.floor(Math.random() * (i + 1));
    let itemAtIndex = input[randomIndex];

    input[randomIndex] = input[i];
    input[i] = itemAtIndex;
  }
  return input;
}	

The way you would use it is as follows:


let tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
tempArray.shuffle();

// and the result is...
console.log(tempArray);		

To learn more about how this code works and the role a few people whose last names are Fisher, Yates, and Knuth played in its creation, read the Shuffling an Array article.

Picking a Random Item

If you need to select an item at random from our array, we can combine some of the concepts from the Random Numbers article and apply it to our array-centric world. The snippet would be:

let value = myArray[Math.floor(Math.random() * myArray.length)];

Here is a fuller example:

let myArray = ["Unos", "Dos", "Tres", "Catorce"];
let value = myArray[Math.floor(Math.random() * myArray.length)];

console.log(value);

To learn more on how this code works, the Picking a Random Item from an Array article goes into more detail.

Merging Arrays

When you have multiple arrays and you want to combine them into a single array, you have a way of doing that by using the spread operator. Take a look at the following example:

let smileys = ["😀", "😇", "😛", "🥶"];
let foods = ["🍊", "🥦", "🍔", "🍕", "🍰"];
let animals = ["🐙", "🐝", "🐈"];

let combined = [...smileys, ...foods, ...animals];
console.log(combined);

We have three arrays called smileys, foods, and animals. By using the spread operator (aka ...), we flatten these arrays into individual items and store the merged contents under the new array called combined.

By the way, if this is the first time you are seeing emojis inside an array are are bit puzzled by it, don't worry. This is totally normal and the Using Emojis in HTML, CSS, and JS article dives further into this wonderful act of nature.

Swapping Items

If you want to swap two items in an array, there are several ways to go about doing this. The quickest approach is to do something as follows:

let myData = ["a", "b", "c", "d", "e", "f", "g"];

let temp = myData[2];
myData[2] = myData[5];
myData[5] = temp;

console.log(myData) // a b f d e c g

For something a bit more reusable, we can use a function whose job it is to swap the items of an array:

let myData = ["a", "b", "c", "d", "e", "f", "g"];

function swap(input, index_A, index_B) {
    let temp = input[index_A];

    input[index_A] = input[index_B];
    input[index_B] = temp;
}

swap(myData, 2, 5);
console.log(myData); // a b f d e c g

The swap function works by taking three arguments:

  1. The array
  2. The first item whose contents we want to swap
  3. The second item whose contents we want to swap

When we pass these three arguments in, the end result is that our specified array will get the items at the specified index positions swapped. If we want to go one step even further, we can extend our Array object with this swapping capability. You can learn more about that and how we generally approached this swapping problem in the Swapping Items in an Array article.

Turning an Array into an Object

The relationship between arrays and objects has always been a bit scandalous. They both allow us to store arbitrary amounts of data. They both have a way of indexing the items. Deep down, an Array is itself an Object...just like everything else in JavaScript. Now, if you ever have the desire to go from an array to an object, the following snippet is for you:

let airportCodes = ["SFO", "LAX", "SEA", "NYC", "ORD", "ATL"];
let airportCodesObject = { ...airportCodes };

console.log(airportCodesObject);

The airportCodesObject will look as follows:

The original array item's index position will be the key, and the corresponding array item's content will be the value.

Reversing our Array

We have the ability to reverse the order items appear in our array by using the built-in reverse method:

let numbers = [1, 2, 3, 4, 5, 6];
numbers.reverse();

console.log(numbers);

The reverse method does modify our original array itself. If you wish prefer to preserve our original array and create a new reversed array instead, we can do the following:

let numbers = [1, 2, 3, 4, 5, 6];
let reversed = [...numbers].reverse();

console.log(reversed);

Yes, the spread operator turns out to be quite the jack-of-all-trades when it comes to dealing with arrays.

Checking if All Array Elements Pass a Test

Arrays have the handy every method that allows us to check if all items in an array pass a test that we specify. For example, the following snippet uses the every method and an isEven function to check if all items in our someNumbers array are even:

let someNumbers = [2, 4, 38, 20, 10, 13, 42];

function isEven(currentItem) {
  if (currentItem % 2 === 0) {
  	return true; 
  }
}

console.log(someNumbers.every(isEven)); // false

Because not all of the items in our someNumbers array are even (looking at you 13), the result is false.

Checking if Some Array Elements Pass a Test

In the previous trick, we saw how the every method returns a true only if all items in the array pass our test. The some method is less picky. This method will return a true if any items in our array pass our test. Take a look at the following example:

let highScores = [46, 191, 38, 10, 156];

function isReallyHighScore(currentItem) {
  if (currentItem > 100) {
  	return true; 
  }
}

console.log(highScores.some(isReallyHighScore)); // true

We have an array of high scores, and the isReallyHighScore function checks if any of the scores are greater than 100. Combining all of this with the some method, the result is true because the values 191 and 156 are indeed greater than 100. It's ok that not all of the scores are greater than 0. That's just how the some method rolls.

Conclusion

Whew. That's a lot of random array-related stuff to digest, but these tricks will come in handy given how often you will use arrays in your day-to-day coding life. I guarantee it. If there are additional array tricks that you know about that I didn't cover, jump into the comments and post them.

Got a question or just want to chat? Comment below or drop by our forums (they are actually the same thing!) where a bunch of the friendliest people you'll ever run into will be happy to help you out!

When Kirupa isn’t busy writing about himself in 3rd person, he is practicing social distancing…even on his Twitter, Facebook, and LinkedIn profiles.

Hit Subscribe to get cool tips, tricks, selfies, and more personally hand-delivered to your inbox.

COMMENTS

Serving you freshly baked content since 1998!
Killer hosting by (mt) mediatemple

Twitter Youtube Facebook Pinterest Instagram Github