Know your Arrays
I find the for
loop very ugly, especially if it is trying to execute a complicated piece of code. Inside the for
loop the code is less readable, it becomes difficult to debug, and it is less modular as the body of the for
loop may not be reusable every time.
I prefer the native methods of an Array
instead of the for
loop to perform common tasks like transforming, filtering or aggregating data.
By using these methods you:
- Makes your code more readable.
- You concentrate on what it does and stop worrying about the index. ( I hate doing
[i]
)
- The intent of your code becomes clearer.
- The code becomes modular and reusable.
- Write less to do more.
And I want to justify this with a few examples.
forEach
The forEach()
method executes a provided function once per array element.
var arr = [{
name: 'john'
}, {
name: 'mary'
}, {
name: 'jane'
}, {
name: 'peter'
}];
I want to capitalize all the names in the array
// A for loop first
var i;
for(i = 0; i < arr.length; i++) {
arr[i].name = arr[i].name.substring(0, 1).toUpperCase() + arr[i].name.substring(1, arr[i].name.length);
}
// Let's try the forEach now
function capitalize(person) {
person.name = person.name.substring(0, 1).toUpperCase() + person.name.substring(1, person.name.length);
}
arr.forEach(capitalize);
The forEach()
pattern is easier to read, the intent is clear and you can re-use the capitalize
method.
I feel that this is even better than the following implementation.
for(i = 0; i < arr.length; i++) {
capitalize(arr[i]);
}
Now I'm going alphabetically
concat
The concat()
method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments.
var array1 = [1,2,3,4,5],
array2 = [6,7,8,9,10],
array3;
array3 = array1.concat(array2);
// [1,2,3,4,5,6,7,8,9,10]
Remember that the original array array1
will not be modified.
every
The every()
method tests whether all elements in the array pass the test implemented by the provided function. It's like a logical AND for all elements of the array.
function isNegative(element) {
return element < 0;
}
[-12, -5, -8, -130, -44].every(isNegative); // true
[-12, -54, 18, -130, -44].every(isNegative); // false
filter
The filter()
method creates a new array with all elements that pass the test implemented by the provided function. Let's say that I want to find all the people whose name have the letter 'e' in them.
function hasTheLetterE(person) {
return (person.name || '').toLowerCase().search(/e/i) > -1;
}
var peopleWithEInTheirName = arr.filter(hasTheLetterE);
peopleWithEInTheirName
will be an array with Jane and Peter.
indexOf
The indexOf()
method returns the first index at which a given element can be found in the array, or -1 if it is not present.
var array = [2, 5, 9];
array.indexOf(2); // 0
array.indexOf(7); // -1
join
The join()
method joins all elements of an array into a string.
var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join(); // assigns 'Wind,Rain,Fire' to myVar1
var myVar2 = a.join(', '); // assigns 'Wind, Rain, Fire' to myVar2
var myVar3 = a.join(' + '); // assigns 'Wind + Rain + Fire' to myVar3
lastIndexOf
The lastIndexOf()
method returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backward, starting at fromIndex.
var array = [2, 5, 9, 2];
array.lastIndexOf(2); // 3
array.lastIndexOf(7); // -1
array.lastIndexOf(2, 3); // 3
array.lastIndexOf(2, 2); // 0
array.lastIndexOf(2, -2); // 0
array.lastIndexOf(2, -1); // 3
map
The map()
method creates a new array with the results of calling a provided function on every element in this array. It's very handy for transforming data.
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots is now [1, 2, 3], numbers is still [1, 4, 9]
pop
The pop()
method removes the last element from an array and returns that element.
var alphabets = ['a', 'b', 'c', 'd'];
console.log(alphabets); // ['a', 'b', 'c', 'd']
var popped = alphabets.pop();
console.log(alphabets); // ['a', 'b', 'c' ]
console.log(popped); // 'd'
push
The push()
method adds one or more elements to the end of an array and returns the new length of the array.
var sports = ['soccer', 'baseball'];
var total = sports.push('football', 'swimming');
console.log(sports); // ['soccer', 'baseball', 'football', 'swimming']
console.log(total); // 4
reduce
The reduce()
method applies a function against an accumulator and each value of the array (from left-to-right) has to reduce it to a single value. This method is extremely useful when you want to aggregate data.
function add(x, y) {
return x + y;
}
var total = [0, 1, 2, 3, 4].reduce(add);
// total == 10
reduceRight()
The reduceRight()
method applies a function against an accumulator and each value of the array (from right-to-left) has to reduce it to a single value.
function concat(a, b) {
return b.concat(a);
}
var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(concat);
// flattened = [0, 1, 2, 3, 4, 5]
reverse()
The reverse()
method reverses an array in place. The first array element becomes the last, and the last array element becomes the first.
var a = ['one', 'two', 'three'];
a.reverse();
// a = ['three', 'two', 'one']
shift()
The shift()
method removes the first element from an array and returns that element. This method changes the length of the array.
var a = [1, 2, 3];
var val = a.shift();
// a = [2, 3]
// val = 1
slice()
The slice()
method returns a new array object selected from begin to end (end not included). The original array will not be modified.
var a = ["zero", "one", "two", "three"];
var sliced = a.slice(1,3);
// a = [ "zero", "one", "two", "three" ]
// sliced = [ "one", "two" ]
some()
The some()
method tests whether some element in the array passes the test implemented by the provided function. It's like a logical OR for all elements of the array.
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
sort()
Probably the most used or required function in your code the sort()
method sorts the elements of an array in place and returns the array. The default sort order is according to string Unicode code points.
var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); // ['apples', 'bananas', 'cherries']
var scores = [1, 10, 21, 2];
scores.sort(); // [1, 10, 2, 21]
// Watch out that 10 comes before 2,
// because '10' comes before '2' in Unicode code point order.
var things = ['word', 'Word', '1 Word', '2 Words'];
things.sort(); // ['1 Word', '2 Words', 'Word', 'word']
// In Unicode, numbers come before upper case letters,
// which come before lower case letters.
Let's take it a notch up. Let's say we want to sort the students according to their ids.
var students = [
{name:'John', id:5},
{name:'Emily', id:3},
{name:'Jane', id:1},
{name:'Jack', id:4},
{name:'Sarah', id:2}
];
function sortById(a, b) {
return a.id > b.id;
}
students.sort(sortById);
// students = [
{"name":"Jane","id":1},
{"name":"Sarah","id":2},
{"name":"Emily","id":3},
{"name":"Jack","id":4},
{"name":"John","id":5}
]
splice()
The splice()
method changes the content of an array by removing existing elements and/or adding new elements. Tricky little one..
var items = ["a", "c", "d", "e"];
items.splice(2, 1);
// items = ["a", "c", "e"]
// here `1` element from index '2' (which was d) got removed
items.splice(1, 0, "b");
// items = ["a", "b", "c", "e"]
// so at position 1 'b' got inserted
// and everything got shifted right
// lets add some back
items.splice(2, 3, "d", "e", "f");
// so from position '2' (from 'c') lets add '3' more elements d, e, f
// items = ["a", "b", "d", "e", "f"]
unshift()
The unshift()
method adds one or more elements to the beginning of an array and returns the new length of the array.
var a = [1, 2, 3];
a.unshift(4, 5);
// a = [4, 5, 1, 2, 3]