Sometimes we need to store a list of values. Who's coming to dinner? What were the team's scores for the season?

Arrays are ordered lists of data. Each item in the list is called an element, which we can access by the element's index.

var guests = ["Alice", "Charles", "Dave", "Bob"];
var scores = [10, 15, 12, 17, 3, 11, 23];
var bananas = [true, 0, "Today"]; // Yes! We Have No Bananas

Once we have an array, we can loop over its elements the same way we loop over a string's characters. We can add and remove elements, change each element, and even sort the array any way we like.

Above we use square brackets to denote an Array literal. There are other ways to create arrays, but this is the most useful.

Array Elements

If we try to output an array, we'll see the contents of the array as a string:

console.log(guests); // "Alice,Charles,Dave,Bob"
console.log(scores); // "10,15,12,17,3,11,23"

Note how the order of the elements is kept intact; no sorting takes place.

We can access elements of an array by index:

guests[0]; // "Alice"
guests[2]; // "Dave"

We can find out how many elements are in an array with the length property:

scores.length; // 7
for (var i = 0; i < scores.length; i += 1) {
  console.log(i + ": " + scores[i]);
}

Creating an Array from a String

We can create an array from a string with the split method:

String.split( delimiter )

var guests = "Alice,Charles,Dave,Bob".split(',');
var scores = "9 15 12 17 3 11 23".split(' ');
guests.length; // 4
scores.length; // 7

Creating a String from an Array

Usually, when an array is output, it will be coerced into a string:

alert(guests); // "Alice,Charles,Dave,Bob"
alert(scores); // "9,15,12,17,3,11,23"

However, when using console.log or the like, the console panel will often show you the array in literal form.

We get more control over converting an array to a string using the join method:

Array.join( separator = ',' )

It coerces each element's value to a string, and concatenates them, separating each element string with the separator, which defaults to ,.

scores.join(); // "9,15,12,17,3,11,23"
scores.join(" "); // "9 15 12 17 3 11 23"
guests.join(', '); // "Alice, Charles, Dave, Bob"
guests.join(' & '); // "Alice & Charles & Dave & Bob"

Modifying an Array

We can modify an element in an array:

guests[2] = "Steve";
guests; // "Alice,Charles,Steve,Bob"
scores[0] = 9;
scores; // "9,15,12,17,3,11,23"

We can add elements onto the end of an array with the push method:

scores.push(11);
scores; // "9,15,12,17,3,11,23,11"
scores.length; // 8

guests.push("Elaine", "Frodo");
guests; // "Alice,Charles,Steve,Bob,Elaine,Frodo"
guests.length; // 6

JavaScript can also take elements off the end of an array with pop:

var lastGuest = guests.pop();
guests; // "Alice,Charles,Steve,Bob,Elaine"
guests.length; // 5
lastGuest; // "Frodo"

We can also add and remove elements from the start of an array with unshift and shift:

guests.unshift("Gollum", "Samwise", "Merry", "Pippin");
guests; // "Gollum,Samwise,Merry,Pippen,Alice,Charles,Steve,Bob,Elaine"
guests.length; // 9
var unableToAttend = guests.shift();
unableToAttend; // "Gollum"

Deleting and adding elements into an array is possible with splice:

Array.splice( start, deleteCount [, item1 [, item2...]] )

guests.splice(5, 2);
guests; // "Samwise,Merry,Pippen,Alice,Charles,Elaine"
guests.splice(3,0,"Frodo");
guests; // "Samwise,Merry,Pippen,Frodo,Alice,Charles,Elaine"
guests.splice(1,0,"Bilbo","Gandalf");
guests; // "Samwise,Bilbo,Gandalf,Merry,Pippen,Frodo,Alice,Charles,Elaine"

The modify functions

    unshift      shift
          │      ▲
          │      │
       ┌──▼──────┴─┐
      0│   Frodo   │
       ├───────────┤
      1│    Sam    │ ───▶
       ├───────────┤      splice
      2│   Merry   │ ◀───
       ├───────────┤
      3│  Pippin   │
       └─▲───────┬─┘
         │       │
         │       ▼
      push       pop

Sorting an array

The sort method is a very interesting one. It sorts an array's elements into order.

Array.sort( [ compareFunction ]);

var fruit = ['apple', 'banana', 'Cherry'];
fruit.sort();
fruit; // "Cherry,apple,banana" <-- not sorted alphabetically

var ages = [15, 20, 2, 11, 9, 10];
ages.sort();
ages; // "10,11,15,2,20,9" <-- not sorted numerically

But as you can see, it doesn't really work the way you want. sort coerces each element into a string, then sorts the strings according to Unicode code point order. In Unicode, Number characters are before the letters, and capital letters are before the lower case letters. At least the numbers and letters are in numeric and alphabetical order.

So sort is case sensitive to a tee, and prefers numbers to letters. However, we can teach sort in many different ways, by providing it a compare function. This function accepts two parameters, often called a and b, and returns -1 if a < b, or 1 if a > b, or 0 if they are equal.

function compare(a, b) {
  console.log(a + " vs " + b);
  if (a < b) {
    return -1;
  }
  if (a > b) {
    return 1;
  }
  // by elimination, a must be equal to b.
  return 0;
}

Of course, the above compare function does exactly the same thing as sort by itself, except it does not coerce elements to strings.

fruit.sort(compare); // ["Cherry", "apple", "banana"]
console.log('---');
ages.sort(compare); // [2, 9, 10, 11, 15, 20] <-- numerically ascending!

Output:

Cherry vs apple
apple vs banana
---
20 vs 15
20 vs 11
15 vs 11
20 vs 10
15 vs 10
11 vs 10
20 vs 9
15 vs 9
11 vs 9
10 vs 9
20 vs 2
15 vs 2
11 vs 2
10 vs 2
9 vs 2

Please note that we do not call compare when we pass it to sort. sort will call compare each time it needs to compare two elements.

// WRONG:
fruit.sort(compare());

// CORRECT:
fruit.sort(compare);

Aside: Functions in JavaScript are fully fledged values. You can put them in variables and pass them as arguments and even have a function return a function. In computer programming, this is called an anonymous function

Sorting Arrays of Numbers

The above function is a good explanation, but if we wish to sort numerically, this compareNumbers function is much better.

function compareNumbersAscending(a, b) {
  return a - b;
}
function compareNumbersDescending(a, b) {
  return b - a;
}

var ages = [15, 20, 2, 11, 9, 10];
ages.sort(compareNumbersAscending); // [2, 9, 10, 11, 15, 20]
ages.sort(compareNumbersDescending); // [20, 15, 11, 10, 9, 2]

The compareNumbersAscending still returns a positive or negative number, or zero. compareNumbersDescending does the same thing, only larger numbers come first.

Sorting Arrays of Strings Alphabetically

Here are some compare functions for sorting arrays of strings, case insensitively:

function compareStringsAscending(a, b) {
  return a.toLowerCase() - b.toLowerCase();
}

var fruit = ["apple", "banana", "Cherry", "dates"];
fruit.sort(compareStringsAscending);

Notes about Sorting

Sorting is one of the more processor-intensive things you can ask a computer to do, and the more elements to sort, the longer it takes. While sorting ~100 things shouldn't take a lot of time on today's computers, doing that sort unnecessarily could slow the program down.

JavaScript should use an appropriately efficient sorting algorithm (which is these days is Quick Sort), and we just need to provide the compare function.

Exercises

Reading Arrays

  • Write a function that takes an array of elements and returns true if all the elements are strings.
  • Write one function for each of the following that takes an array of unsorted numbers and returns a number:
    • the average or mean (sum of elements ÷ count of elements)
    • the minimum number (smallest element)
    • the maximum number (largest element)
    • the median (the middle element when sorted)
    • Extra for experts: the mode (the element that appears most frequently, false if nothing is repeated)
  • Write a function that takes an array of people's names ['Alice', 'Bob', 'Charles'] and output a proper English sentence: "Alice, Bob, and Charles". See how every name is separated with a comma, except the last one which is preceded by 'and'.
  • Using an array of ranks and an array of suits, write a set of nested loops that outputs every playing card: Ranks: Ace, 2—10, Jack, Queen, King. Suits: Clubs, Diamonds, Hearts, Spades.
    • Extra for experts: do it using % and a single for loop.
  • Using an array of months and an array of days in each month, write a program that outputs each day of the year:
1 January
2 January
3 January
…
30 January
31 January
1 February
2 February
…
29 November
30 November
1 December
…
31 December

Creating Arrays

  • Write a function that takes an array of string elements and returns a new array of only the elements that contain strings longer than 5 characters.
  • Write a function that takes an array of numbers and returns a new array of each element squared (i.e. 3 squared = 3² = 3 ✕ 3 = 9), (e.g. [3, 10, 42] => [9, 100, 1764])

Sorting Arrays

  • Write a function that sorts an array of numbers numerically, with largest numbers coming last (ascending).
  • Write a function that takes an array of string elements and sorts the array by length of string with longest strings coming first (descending).
  • Write a function that takes an array of string elements and sorts the array by each element's vowel count, with highest vowel count coming last (ascending).