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>:lengthcounts the items,includeschecks for one, andindexOffinds it or gives-1. pushandpopadd and remove at the end;unshiftandshiftadd and remove at the start.filter,map,findandreducedo the jobs of LINQ'sWhere,Select,FirstOrDefaultandSum, and never change the original array.reducetakes 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.