Let us start with something simple: producing an array of length n whose first element is 0, second element is 1, etc.
> var arr = [null, null, null];
> arr.map(function (x, i) { return i })
[ 0, 1, 2 ]
Alas, map() skips holes, but preserves them [2], which is why an empty array (with only holes) does not work for us:
> new Array(3).map(function (x, i) { return i })
[ , , ]
The next two sections look at ways of creating an array with a given length.
Array(undefined, undefined, undefined)
Array.apply(null, Array(3))
If we combine this trick with map(), we get what we wanted:
function fillArrayWithNumbers(n) {
var arr = Array.apply(null, Array(n));
return arr.map(function (x, i) { return i });
}
The function in action:
> fillArrayWithNumbers(5)
[ 0, 1, 2, 3, 4 ]
> _.range(5)
[ 0, 1, 2, 3, 4 ]
The previous trick with apply() is not very self-explanatory and Underscore.js is as close to a standard as it gets. Therefore, it is best to create filled arrays via _.range(). If we want to fill the array with something other than a range of numbers, we can use map():
> _.range(3).map(function () { return 'a' })
[ 'a', 'a', 'a' ]
Let’s use _.range() to set up a matrix for Tic-tac-toe. We initialize all arrays correctly:
var ticTacToe = _.range(3).map(function () {
// Create one row
return _.range(3).map(function () {
return '.';
});
});
ticTacToe[0][2] = 'X'; // [row][column]
ticTacToe.forEach(function (row) {
console.log(row.join(' '));
});
Output:
. . X
. . .
. . .