- The below is an example of the simplest implementation of an array data structure. This is known as a one-dimensional array, meaning it only has one level, or that it does not have any other arrays nested within it.
let simpleArray = ['one', 2, 'three', true, false, undefined, null];
console.log(simpleArray.length);
// logs 7
- A more complex implementation of an array can be seen below. This is known as a multi-dimensional array, or an array that contains other arrays.
let complexArray = [
[
{
one: 1,
two: 2
},
{
three: 3,
four: 4
}
],
[
{
a: "a",
b: "b"
},
{
c: "c",
d: "d"
}
]
];
- JavaScript arrays are zero-indexed, meaning that the first element of an array is actually at the zeroth position.
- In order to retrieve an element from an array we can enclose an index in brackets and append it to the end of an array, or more commonly, to a variable which references an array object. This is known as bracket notation.
- Arrays are mutable
- The
push()
method adds elements to the end of an array, andunshift()
adds elements to the beginning.
let twentyThree = 'XXIII';
let romanNumerals = ['XXI', 'XXII'];
romanNumerals.unshift('XIX', 'XX');
// now equals ['XIX', 'XX', 'XXI', 'XXII']
romanNumerals.push(twentyThree);
// now equals ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']
//Notice that we can also pass variables,
//which allows us even greater flexibility in dynamically modifying our array's data.
pop()
removes an element from the end of an array, whileshift()
removes an element from the beginning.- Example:
let greetings = ['whats up?', 'hello', 'see ya!'];
greetings.pop();
// now equals ['whats up?', 'hello']
greetings.shift();
// now equals ['hello']
let popped = greetings.pop();
// returns 'hello'
// greetings now equals []
splice()
allows us to do just that: remove any number of consecutive elements from anywhere in an array.splice()
can take up to 3 parameters, but for now, we'll focus on just the first 2.splice()
's first parameter represents the index on the array from which to begin removing elements, while the second parameter indicates the number of elements to delete.- Example:
let array = ['today', 'was', 'not', 'so', 'great'];
array.splice(2, 2);
// remove 2 elements beginning with the 3rd element
// array now equals ['today', 'was', 'great']
let newArray = array.splice(3, 2);
// newArray equals ['not', 'so']
- you can use the third parameter, comprised of one or more element(s), to add to the array. This can be incredibly useful for quickly switching out an element, or a set of elements, for another.
- Example:
- Note that there can be any number of elements (separated by commas) following
amountToDelete
, each of which gets inserted.
const numbers = [10, 11, 12, 12, 15];
const startIndex = 3;
const amountToDelete = 1;
numbers.splice(startIndex, amountToDelete, 13, 14);
// the second entry of 12 is removed, and we add 13 and 14 at the same index
console.log(numbers);
// returns [ 10, 11, 12, 13, 14, 15 ]
slice()
, rather than modifying an array, copies, or extracts, a given number of elements to a new array, leaving the array it is called upon untouched.slice()
takes only 2 parameters — the first is the index at which to begin extraction, and the second is the index at which to stop extraction (extraction will occur up to, but not including the element at this index).- Example:
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
let todaysWeather = weatherConditions.slice(1, 3);
// todaysWeather equals ['snow', 'sleet'];
// weatherConditions still equals ['rain', 'snow', 'sleet', 'hail', 'clear']
-
ES6's new spread operator allows us to easily copy all of an array's elements, in order, with a simple and highly readable syntax. The spread syntax simply looks like this:
...
-
Example 1:
let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];
// thatArray equals [true, true, undefined, false, null]
// thisArray remains unchanged, and is identical to thatArray
- Eaxmple 2:
function copyMachine(arr, num) {
let newArr = [];
while (num >= 1) {
// Only change code below this line
newArr.push([...arr]);
// Only change code above this line
num--;
}
return newArr;
}
console.log(copyMachine([true, false, true], 2));
- Another huge advantage of the spread operator, is the ability to combine arrays, or to insert all the elements of one array into another, at any index.
- With more traditional syntaxes, we can concatenate arrays, but this only allows us to combine arrays at the end of one, and at the start of another.
- Example:
let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];
let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];
// thatArray now equals ['basil', 'cilantro', 'sage', 'rosemary', 'parsley', 'thyme', 'coriander']
- Since arrays can be changed, or mutated, at any time, there's no guarantee about where a particular piece of data will be on a given array, or if that element even still exists.
indexOf()
, that allows us to quickly and easily check for the presence of an element on an array.indexOf()
takes an element as a parameter, and when called, it returns the position, or index, of that element, or-1
if the element does not exist on the array.- Example 1:
let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
fruits.indexOf('dates'); // returns -1
fruits.indexOf('oranges'); // returns 2
fruits.indexOf('pears'); // returns 1, the first index at which the element exists
- Example 2:
indexOf()
can be incredibly useful for quickly checking for the presence of an element on an array. We have defined a function,quickCheck
, that takes an array and an element as arguments. Modify the function usingindexOf()
so that it returnstrue
if the passed element exists on the array, andfalse
if it does not.
function quickCheck(arr, elem) {
if (arr.indexOf(elem) >= 0) {
return true;
}
return false;
}
console.log(quickCheck(["squash", "onions", "shallots"], "mushrooms"));
function quickCheck(arr, elem) {
return arr.indexOf(elem) >= 0 ? true : false;
}
console.log(quickCheck(["squash", "onions", "shallots"], "mushrooms"));
function quickCheck(arr, elem) {
return arr.indexOf(elem) != -1;
}
console.log(quickCheck(["squash", "onions", "shallots"], "mushrooms"));
- JavaScript offers several built in methods that each iterate over arrays in slightly different ways to achieve different results (such as
every()
,forEach()
,map()
, etc.), however the technique which is most flexible and offers us the greatest amount of control is a simplefor
loop. - Example 1:
function greaterThanTen(arr) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] > 10) {
newArr.push(arr[i]);
}
}
return newArr;
}
greaterThanTen([2, 12, 8, 14, 80, 0, 1]);
// returns [12, 14, 80]
- Example 2:
- filteredArray([ ["trumpets", 2], ["flutes", 4], ["saxophones", 2] ], 2) should return [ ["flutes", 4] ]
- filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3) should return [ ]
function filteredArray(arr, elem) {
let newArr = [];
// change code below this line
for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf(elem) == -1) {
//Checks every parameter for the element and if is NOT there continues the code
newArr.push(arr[i]); //Inserts the element of the array in the new filtered array
}
}
// change code above this line
return newArr;
}
// change code here to test different cases:
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
- arrays can contain an infinite depth of arrays that can contain other arrays, each with their own arbitrary levels of depth, and so on. In this way, an array can very quickly become very complex data structure, known as a multi-dimensional, or nested array.
- objects are just collections of key-value pairs, or in other words, pieces of data mapped to unique identifiers that we call properties or keys.
- Example 1:
let FCC_User = {
username: 'awesome_coder',
followers: 572,
points: 1741,
completedProjects: 15
};
// **This is called dot notation
let userData = FCC_User.followers;
// userData equals 572
// ** with bracket notation
let userData = FCC_User['followers'];
// userData equals 572
- Example 2:
let foods = {
apples: 25,
oranges: 32,
plums: 28
};
foods.bananas = 13;
foods.grapes = 35;
foods['strawberries'] = 27;
console.log(foods);
- Example:
let nestedObject = {
id: 28802695164,
date: 'December 31, 2016',
data: {
totalUsers: 99,
online: 80,
onlineStatus: {
active: 67,
away: 13
}
}
};
- Example 1:
- This code will evaluate the value stored in the
selectedFood
variable and return the value of that key in thefoods
object, orundefined
if it is not present. Bracket notation is very useful because sometimes object properties are not known before runtime or we need to access them in a more dynamic way.
let selectedFood = getCurrentFood(scannedItem);
let inventory = foods[selectedFood];
- Example:
let foods = {
apples: 25,
oranges: 32,
plums: 28,
bananas: 13,
grapes: 35,
strawberries: 27
};
delete foods.oranges;
delete foods.plums;
delete foods.strawberries;
console.log(foods);
One uses the hasOwnProperty() method and the other uses the in keyword. If we have an object users with a property of Alan, we could check for its presence in either of the following ways:
users.hasOwnProperty('Alan');
'Alan' in users;
// both return true
- Example:
- We've created an object,
users
, with some users in it and a functionisEveryoneHere
, which we pass theusers
object to as an argument. Finish writing this function so that it returnstrue
only if theusers
object contains all four names,Alan
,Jeff
,Sarah
, andRyan
, as keys, andfalse
otherwise.
- We've created an object,
let users = {
Alan: {
age: 27,
online: true
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: true
},
Ryan: {
age: 19,
online: true
}
};
function isEveryoneHere(obj) {
if (
obj.hasOwnProperty("Alan") &&
obj.hasOwnProperty("Jeff") &&
obj.hasOwnProperty("Sarah") &&
obj.hasOwnProperty("Ryan")
) {
return true;
}
return false;
}
let users = {
Alan: {
age: 27,
online: true
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: true
},
Ryan: {
age: 19,
online: true
}
};
function isEveryoneHere(obj) {
return ["Alan", "Jeff", "Sarah", "Ryan"].every(name =>
obj.hasOwnProperty(name)
);
}
- Example 1:
- we defined a variable
user
, and as you can see, this variable was reset during each iteration to each of the object's keys as the statement looped through the object, resulting in each user's name being printed to the console.
- we defined a variable
- NOTE: Objects do not maintain an ordering to stored keys like arrays do; thus a key's position on an object, or the relative order in which it appears, is irrelevant when referencing or accessing that key.
for (let user in users) {
console.log(user);
}
// logs:
Alan
Jeff
Sarah
Ryan
- Example 2:
- We've defined a function
countOnline
which accepts one argument (a users object). Use a for...in statement within this function to loop through the users object passed into the function and return the number of users whoseonline
property is set totrue
. An example of a users object which could be passed tocountOnline
is shown below. Each user will have anonline
property with either atrue
orfalse
value.
- We've defined a function
let users = {
Alan: {
age: 27,
online: false
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: false
},
Ryan: {
age: 19,
online: true
}
};
function countOnline(obj) {
// change code below this line
let result = 0;
for (let user in obj) {
if (obj[user].online === true) {
result++;
}
}
return result;
// change code above this line
}
console.log(countOnline(users));
- We can also generate an array which contains all the keys stored in an object using the Object.keys() method and passing in an object as the argument.
- This will return an array with strings representing each property in the object.
- there will be no specific order to the entries in the array.
Example :
let users = {
Alan: {
age: 27,
online: false
},
Jeff: {
age: 32,
online: true
},
Sarah: {
age: 48,
online: false
},
Ryan: {
age: 19,
online: true
}
};
function getArrayOfUsers(obj) {
return Object.keys(obj);
}
console.log(getArrayOfUsers(users));
// return [ 'Alan', 'Jeff', 'Sarah', 'Ryan' ]
- Example:
- The
user
object contains three keys. Thedata
key contains five keys, one of which contains an array offriends
. From this, you can see how flexible objects are as data structures. We've started writing a functionaddFriend
. Finish writing it so that it takes auser
object and adds the name of thefriend
argument to the array stored inuser.data.friends
and returns that array.
- The
let user = {
name: "Kenneth",
age: 28,
data: {
username: "kennethCodesAllDay",
joinDate: "March 26, 2016",
organization: "freeCodeCamp",
friends: ["Sam", "Kira", "Tomo"],
location: {
city: "San Francisco",
state: "CA",
country: "USA"
}
}
};
function addFriend(userObj, friend) {
userObj.data.friends.push(friend);
return userObj.data.friends;
}
console.log(addFriend(user, "Pete"));