Arrays

A JavaScript array works like a C# List<T>. It grows and shrinks with push, pop, shift and unshift, and has length, includes and indexOf. Its filter, map, find and reduce methods do the jobs of LINQ's Where, Select, First and Sum.

Apprentice · JavaScript · Updated

After this lesson you can

  • Add and remove array items with push, pop, shift and unshift, and look them up with length, includes and indexOf
  • Filter, transform and total arrays with filter, map, find and reduce, like LINQ's Where, Select, First and Sum

Key takeaways

  • A JavaScript array works like a C# List<T>: length counts the items, includes checks for one, and indexOf finds it or gives -1.
  • push and pop add and remove at the end; unshift and shift add and remove at the start.
  • filter, map, find and reduce do the jobs of LINQ's Where, Select, FirstOrDefault and Sum, and never change the original array.
  • reduce takes a function and a starting value. The function gets the running total and the next item, and returns the new total.
  • sort() on its own sorts as text, so sort numbers with a compare function: numbers.sort((a, b) => a - b).

A JavaScript array is written with square brackets, and it behaves much more like a C# List<T> than a C# array: it grows and shrinks as you go.

const names = ['Emma', 'Liam', 'Olivia'];

console.log(names[0]);
console.log(names.length);
console.log(names.includes('Liam'));
console.log(names.indexOf('Olivia'));
console.log(names.indexOf('Noah'));
Emma
3
true
2
-1
JavaScript C# List<T>
names[0] names[0]
names.length names.Count
names.includes('Liam') names.Contains("Liam")
names.indexOf('Olivia'), -1 when it isn't there names.IndexOf("Olivia"), also -1

One difference: reading past the end, such as names[10], gives undefined instead of throwing an exception.

Adding and removing

Four methods add and remove items at the two ends:

Method Does Returns
push(item) Adds to the end The new length
pop() Removes from the end The item it removed
unshift(item) Adds to the start The new length
shift() Removes from the start The item it removed
const numbers = [];

numbers.push(7);
numbers.push(21);
numbers.push(3);
console.log(numbers.join(', '));

const last = numbers.pop();
console.log(`${last} came off the end: ${numbers.join(', ')}`);

numbers.unshift(35);
console.log(numbers.join(', '));

const first = numbers.shift();
console.log(`${first} came off the start: ${numbers.join(', ')}`);
7, 21, 3
3 came off the end: 7, 21
35, 7, 21
35 came off the start: 7, 21

join(', ') turns an array into one string, with ', ' between the items, like C#'s string.Join. And the array is a const, yet it changed: const only stops numbers being given a whole new array.

push and pop together make a stack, like C#'s Stack<T>; push and shift make a queue, like Queue<T>.

Looping

for...of goes through the items, like foreach:

const names = ['Emma', 'Liam', 'Olivia'];

for (const name of names) {
    console.log(`Hello, ${name}`);
}
Hello, Emma
Hello, Liam
Hello, Olivia

Careful: it's of. There's also a for...in, which goes through the positions ('0', '1', '2') instead of the items.

LINQ, JavaScript style

Arrays have methods that take a function, just like LINQ's take a lambda:

const scores = [72, 95, 48, 88, 61];

const passes = scores.filter(score => score >= 60);
const curved = scores.map(score => score + 5);
const firstFail = scores.find(score => score < 60);
const total = scores.reduce((sum, score) => sum + score, 0);

console.log(passes.join(', '));
console.log(curved.join(', '));
console.log(firstFail);
console.log(total);
console.log(scores.some(score => score > 90));
console.log(scores.every(score => score > 40));
72, 95, 88, 61
77, 100, 53, 93, 66
48
364
true
true
JavaScript LINQ Gives
filter(...) Where(...) The items the function is true for, as a new array
map(...) Select(...) A new array, each item changed by the function
find(...) FirstOrDefault(...) The first match, or undefined
reduce(...) Sum(...), Aggregate(...) One value, built up item by item
some(...), every(...) Any(...), All(...) true or false

score => score >= 60 is an arrow function: JavaScript's lambda. The next lesson looks at them closely.

reduce takes two arguments: a function, and the starting value (0 here). The function gets the running total so far and the next item, and returns the new running total: 0 + 72, then 72 + 95, and so on.

Unlike LINQ, these methods run at once and return real arrays; there's no deferred execution, and no ToList() needed. They never change the original array.

Sorting needs a function

One trap for C# developers: sort() on its own sorts items as text, and changes the array itself:

const numbers = [10, 9, 100, 1];

numbers.sort();
console.log(numbers.join(', '));

numbers.sort((a, b) => a - b);
console.log(numbers.join(', '));
1, 10, 100, 9
1, 9, 10, 100

As text, '100' comes before '9', just as apple comes before banana. To sort numbers, give sort a function that compares two items: negative when a goes first, positive when b does. a - b is exactly that.

Check yourself

2 questions to try on the lesson page.

So what

A JavaScript array is a List<T> with LINQ built in: push and pop to change it, filter, map, find and reduce to ask it questions. Just remember to give sort a compare function for numbers.

Key terms

Cheat sheets