Day 5. Arrays_Exercise


Level 1 / Level 2 / Level 3

👟Level 1.

5) Declare an array called mixedDataTypes, put different data types in the array and find the length of the array. The array size should be greater than 5.
const mixedDataTypes = [
    'Vanya', 
    7,
    true,
    'white violin', 
    'Hargreeves', 
    { umbrella_academy: ['number 1', 'number 2', 'number 3', 'number 4', 'number 5', 'number 6', 'number 7'] } 
];
console.log(mixedDataTypes.length);  //6


9) Print the first company, middle and last company.
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
console.log(itCompanies[0], itCompanies[3], itCompanies[6]);  //Facebook Apple Amazon

I tried to print them out with itCompanies.index[0]. Probably, I thought it as some kind of array method. It doesn’t work.

To access an item of an array, use array[index]

let middle = (itCompanies.length - 1) / 2;
let last = itCompanies.length - 1;
console.log(itCompanies[0], itCompanies[middle], itCompanies[last]);  //Facebook Apple Amazon

This worked out too. Actually, this way of approach is way better afterwards.


10) Print out each company.
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
console.log(itCompanies.toString());  //Facebook,Google,Microsoft,Apple,IBM,Oracle,Amazon
console.log(itCompanies.join(' '));  //Facebook Google Microsoft Apple IBM Oracle Amazon

I first thought ‘OK, Let’s split the array!’ but the truth is split() is for strings. Instead, I used toString to print out each company’s name. Then I used join to space out each names.

toString doesn’t have any parameters by default. If I want to seperate the items of an array as a string, use join!


11) Change each company name to uppercase one by one and print them out.
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
itCompanies[0] = itCompanies[0].toUpperCase();
itCompanies[1] = itCompanies[1].toUpperCase();
itCompanies[2] = itCompanies[2].toUpperCase();
itCompanies[3] = itCompanies[3].toUpperCase();
itCompanies[4] = itCompanies[4].toUpperCase();
itCompanies[5] = itCompanies[5].toUpperCase();
itCompanies[6] = itCompanies[6].toUpperCase();
console.log(itCompanies);  //(7) ['FACEBOOK', 'GOOGLE', 'MICROSOFT', 'APPLE', 'IBM', 'ORACLE', 'AMAZON']

The items of an array are mutable(modifiable)! I only have to reassign a value.


12) Print the array like as a sentence: Facebook, Google, Microsoft, Apple, IBM, Oracle and Amazon are big IT companies.
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
itCompanies[6] = 'and Amazon';
console.log(`${itCompanies.join(', ')} are big IT companies.`);

I’m not sure if modifying the last element of an array would be the best way.

I came back from Day 9. A better solution for adding and before the last element would be this:

const itCompanies =  ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
let itCompaniesWithoutLast = itCompanies.slice(0, itCompanies.length - 1);
let lastItCompany = itCompanies[itCompanies.length - 1];
console.log(`${itCompaniesWithoutLast.join(', ')} and ${lastItCompany} are big IT companies.`);
// Facebook, Google, Microsoft, Apple, IBM, Oracle and Amazon are big IT companies.


13) Check if a certain company exists in the itCompanies array. If it exist return the company else return a company is not found.
//using includes()
let company = prompt('What company do you want to find?');
let inclusion = itCompanies.includes(company);
if (inclusion === true) {
    console.log(company);
} else {
    console.log(`${company} is not found.`);
};

//using indexOf()
let company = prompt('What company do you want to find?');
let inclusion = itCompanies.indexOf(company);
if (inclusion === -1) {
    console.log(`${company} is not found.`);
} else {
    console.log(company);
};

I made a prompt so that the user can enter a company name. includes() returns true or false, so I made a condition about it. I can also use indexOf(). indexOf() returns the index if the value exists, or else it would return -1.


14) Filter out companies which have more than one ‘o’ without the filter method.
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
let pattern = /o/gi;
console.log(itCompanies[0].match(pattern));  //(2) ['o', 'o']
console.log(itCompanies[1].match(pattern));  //(2) ['o', 'o']
console.log(itCompanies[2].match(pattern));  //(2) ['o', 'o']
console.log(itCompanies[3].match(pattern));  //null
console.log(itCompanies[4].match(pattern));  //null
console.log(itCompanies[5].match(pattern));  //['O']
console.log(itCompanies[6].match(pattern));  //['o']

I wanted to set another variable of index and make it loop through the index numbers, but for now I’m not sure how it works. So, I set a regular expression and used match() to determine if the element of the array has more than one ‘o’. match() will return the array if there’s a match, so unless the returned value is null, it has more than one ‘o’.

  • I’m back here from Day 6, and the code using loop would be:
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
let pattern = /o/gi;
for (let i = 0; i < itCompanies.length; i++) {
    if (itCompanies[i].match(pattern)) {
        console.log(itCompanies[i]);
    }
}  //Facebook Google Microsoft Oracle Amazon


  • If the condition was to find more than two ‘o’s:
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
let pattern = /o/gi;
for (let i = 0; i < itCompanies.length; i++) {
  if (itCompanies[i].match(pattern) && itCompanies.match(pattern).length >= 2) {
    console.log(itCompanies[i]);
  }
}  //Facebook Google Microsoft


  • On 30DaysOfJS Chat, I found another idea of solving the problem:
const itCompanies = ['Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'];
for (let i = 0; i < itCompanies.length; i++) {
  let myStr = itCompanies[i].toLowerCase();
  let count = 0;
  let position = myStr.indexOf('o');
  while ( position != -1 ) {
    count++;
    position = myStr.indexOf('o', position + 1);
  }
  if (count >= 2) {
    console.log(itCompanies[i]);
  }
}

I thought this idea using while and indexOf() was great. At first I wasn’t sure about the position + 1 part, so I looked up the document.

indexOf() can take up to two parameters. The second parameter is called position, and returns the index of the first occurrence of the specified substring at a position greater than or equal to position, which defaults to 0.

So what the upper code does is this. It takes each elements of the array, and set the variable count to literally count the number of ‘o’. The variable position uses indexOf(), which returns the first occurence of the input(if exists) or -1(if it doesn’t exist). To make the code detect both ‘o’ and ‘O’, I first lowercased all the elements.

Then, the codes within the while loop executes while the position is not -1(=if ‘o’ exists at myStr, indexOf() will return a number that’s not -1). If ‘o’ exists, the code increments count by 1, and move the position to one character ahead. In other words, the range of the search is moved after the last ‘o’ that is found. This idea really got me. So, the code will run through all the elements, and after that, it’ll print the element whose count is more than 2.

Though, I had a suggestion that while could be quite dangerous, because if the condition to execute the while loop is wrong, it can crash the browser. I read a document again, and it had a note that says ‘Use the break statement to stop a loop before condition evaluates to true.’.


18) Slice out the last 3 companies from the array.
console.log(itCompanies.slice(4, 6));  //(2) ['IBM', 'Oracle']
console.log(itCompanies.slice(4));  //(3) ['IBM', 'Oracle', 'Amazon']

Remember, slice() doesn’t include the ending position. If I want to slice from starting point to the end, the argument for the ending position should be empty so that it could be included.


19) Slice out the middle IT company or companies from the array.
console.log(itCompanies.slice(1,6));  //(5) ['Google', 'Microsoft', 'Apple', 'IBM', 'Oracle']
console.log(itCompanies.slice(2,5));  //(3) ['Microsoft', 'Apple', 'IBM']
console.log(itCompanies.slice(3,4));  //['Apple']

I wonder if I could make ‘the middle’ into some calculation, making the computer do the work.


23) Remove all IT companies.
console.log(itCompanies.splice());  //[]

splice() is used to remove all the items of an array.


👟Level 2.

1) Create a separate countries.js file and store the countries array in to this file, create a separate file web_techs.js and store the webTechs array in to this file. Access both file in main.js file.

To solve this one, I tracked myself back to Day 1, when I was learning how to add JavaScript to a web page. I made a folder ‘30DaysOfJS’, and created three js files(countries.js, web_techs.js, main.js) and one HTML file(index.html).

I stored each arrays at countries.js and web_techs.js. Then, on the index.html I added JavaScript files with <script> tag. If I open the page of index.html, I can access to both arrays in countries.js and web_techs.js.

<body>
    <script src = "countries.js"></script>
    <script src = "web_techs.js"></script>
    <script src = "main.js"></script>
</body>

The main.js file should be below all the other scripts!


2) First remove all the punctuations and change the string to array and count the number of words in the array.
let text = 'I love teaching and empowering people. I teach HTML, CSS, JS, React, Python.';
//removing all the punctuations
let string = text.replace(/[^\w ]/g, '');
//change the string to array
let arr = string.split(' ');
//count the number of words in the array
console.log(arr.length);  //13

I’ve done similar task at Day 2. Still, I didn’t fully understand why I should put space after \w, so I asked stackoverflow and got the answer. The ^ means ‘not’, so [^\w ] will remove everything except the character classes listed in the bracket(in this case, a word character and a space).

Don’t forget the syntax! Regular expressions starts and ends with delimiters(/), and between them are the things that I want to find or match. After the ending delimiter, I can put g(for global search), or i(for case-insensitive search).

To change the string to an array, I used split(), which was at Day 2. It splits a string at a specified place. In this case I put ' '(a space) at the argument, so the string will be splitted at the spaces.


3) In the following shopping cart add, remove, edit items.
const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
  • Add ‘Meat’ in the beginning of your shopping cart if it has not been already added.
const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
if (shoppingCart.includes('Meat') === false) {
    shoppingCart.unshift('Meat');
    console.log(shoppingCart);
};  //(5) ['Meat', 'Milk', 'Coffee', 'Tea', 'Honey']

At first I set the condition like if (!(shoppingCart.includes('Meat')), but it didn’t work out. Making a condition, I should check if a returned value matches certain value.

includes() is a method used both in strings and arrays. Remember that includes() returns me a Boolean value!


  • Add ‘Sugar’ at the end of you shopping cart if it has not been already added.
const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
if ((shoppingCart.includes('Sugar')) === false) {
    shoppingCart.push('Sugar');
    console.log(shoppingCart);
};  //(5) ['Milk', 'Coffee', 'Tea', 'Honey', 'Sugar']


  • Remove ‘Honey’ if you are allergic to honey.
const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
//the second argument in the prompt will act as a placeholder
let allergyInput = prompt('Are you allergic to honey?', 'Enter Y or N');
if (allergyInput === 'Y') {
    //starting from index 3, remove 1 item
    shoppingCart.splice(3, 1);
    console.log(shoppingCart);
}; //(3) ['Milk', 'Coffee', 'Tea']


  • Modify ‘Tea’ to ‘Green Tea’.
const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
//starting from index 2, remove 1 item, add(replace) it to 'Green Tea'
shoppingCart.splice(2, 1, 'Green Tea');
console.log(shoppingCart);  //(4) ['Milk', 'Coffee', 'Green Tea', 'Honey']

splice() is used for both removing and replacing items of an array. To replace an item is to remove the item and add a new item.

const shoppingCart = ['Milk', 'Coffee', 'Tea', 'Honey'];
//fill 'Green Tea' starting from index 2 before index 3(not included)
shoppingCart.fill('Green Tea',2, 3);
console.log(shoppingCart);  ////(4) ['Milk', 'Coffee', 'Green Tea', 'Honey']

‘fill()` can also used for modifying the given array. It fills the array with a static value from the starting position to the ending position(not included). If I don’t put any parameters other than the value, it will fill every elements of an array. If I put one parameter after the value, it will fill the value from the starting position I put to the end.



4) In countries array check if ‘Ethiopia’ exists in the array if it exists print ‘ETHIOPIA’. If it does not exist add to the countries list.
const countries = [
  'Albania',
  'Bolivia',
  'Canada',
  'Denmark',
  'Ethiopia',
  'Finland',
  'Germany',
  'Hungary',
  'Ireland',
  'Japan',
  'Kenya'
];
if (countries.includes('Ethiopia') === true) {
    console.log('ETHIOPIA');
} else {
    countries.unshift('Ethiopia');
};  //ETHIOPIA

I used unshift(), but I think using push() could also be possible. The only difference will be the position to which ‘Ethiopia’ is added - at the beginning for unshift(), and at the end for push(). Below I checked if the code works by removing ‘Ethiopia’ from the array.

const countries = [
  'Albania',
  'Bolivia',
  'Canada',
  'Denmark',
  'Finland',
  'Germany',
  'Hungary',
  'Ireland',
  'Japan',
  'Kenya'
];
if (countries.includes('Ethiopia') === true) {
    console.log('ETHIOPIA');
} else {
    countries.unshift('Ethiopia');
};
console.log(countries);  //'Ethiopia' is added at the beginning of the array


5) In the webTechs array, check if ‘Sass’ exists in the array and if it exists print ‘Sass is a CSS preprocess’. If it does not exist, add ‘Sass’ to the array and print the array.
const webTechs = [
  'HTML',
  'CSS',
  'JavaScript',
  'React',
  'Redux',
  'Node',
  'MongoDB'
];
if (webTechs.includes('Sass') === true) {
    console.log('Sass is a CSS preprocess.');
} else {
    webTechs.push('Sass');
    console.log(webTechs);
};  //(8) ['HTML', 'CSS', 'JavaScript', 'React', 'Redux', 'Node', 'MongoDB', 'Sass']

Below I checked if the code works by adding ‘Sass’ in the array.

const webTechs = [
  'HTML',
  'CSS',
  'JavaScript',
  'React',
  'Redux',
  'Node',
  'MongoDB',
  'Sass'
];
if (webTechs.includes('Sass') === true) {
    console.log('Sass is a CSS preprocess.');
} else {
    webTechs.push('Sass');
    console.log(webTechs);
};  //Sass is a CSS preprocess.


6) Concatenate the following two variables and store it in a fullStack variable.
const frontEnd = ['HTML', 'CSS', 'JS', 'React', 'Redux']
const backEnd = ['Node','Express', 'MongoDB']

console.log(fullStack)
const frontEnd = ['HTML', 'CSS', 'JS', 'React', 'Redux'];
const backEnd = ['Node','Express', 'MongoDB'];
const fullStack = frontEnd.concat(backEnd);
console.log(fullStack);

I cannot concatenate two arrays like concat(frontEnd, backEnd). This syntax only works for strings, where concat() takes several substrings as its arguments and joins them.


👟Level 3.

1) The following is an array of 10 students ages:
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24]
  • Sort the array and find the min and max age.
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
console.log(`min: ${sortedAges[0]}, max: ${sortedAges[sortedAges.length - 1]}`);
//min: 19, max: 26

After the sorting, the array’s first item would be min, and the last item max. I used sortedAges[sortedAges.length - 1] to get the value of the last index. I used string literals to print out the returned values.

const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
console.log(Math.min(...sortedAges));  //19
console.log(Math.max(...sortedAges));  //26

For another approach, I wanted to use Math.min() and Math.max(), but I couldn’t log the returned value when I put the code like Math.min(ages). It returned NaN(Not a Number) all the time.

I wondered if there’s a way that I could use the math object, so I looked up the MDN document of Math.min(). On the top of the page is the syntax of the method, and I found out that I should add three dots before the name of an array. I think those three dots indicate that the following name is an array.

Besides, using Math.min() and Math.max() would make the sorting process unnecessary.


  • Find the median age(one middle item OR two middle items divided by two).
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
let median = sortedAges.length / 2;
console.log(sortedAges[median]);  //24

To get the median age, I should arrange the numbers from the smallest to the largest first. Then, I can find the median value that is positioned at the middle.

I wanted to specify more cases, depending on whether the length of ages is an even number or an odd number. If the length of an array is an even number, I should add two values in the middle and divide it by 2. Else, the median value would be just the one in the middle.

const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
if ((sortedAges.length) % 2 === 0 ) {
    let median = (sortedAges.length / 2) - 1 ;
    console.log((sortedAges[median] + sortedAges[median + 1]) / 2);
} else {
    let median = (sortedAges.length + 1) / 2;
    console.log(sortedAges[median]);
};

I thought the upper code was right, but actually it wasn’t. I didn’t consider the fact that an index of an array starts with 0. So the 7th line was wrong.

If the length is an even number, I should divide it by 2, and subtract 1 afterwards. If the length is an odd number, I should subtract 1 first, and then divide it by 2.


Below is the final answer of more specified version.

const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
if ((sortedAges.length) % 2 === 0 ) {
    let median = (sortedAges.length / 2) - 1;
    console.log((sortedAges[median] + sortedAges[median + 1]) / 2);
} else {
    let median = (sortedAges.length - 1) / 2;
    console.log(sortedAges[median]);
};


  • Find the average age(all items divided by number of items).
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
const ageSum = ages[0] + ages[1] + ages[2] + ages[3] + ages[4] + ages[5] + ages[6] + ages[7]+ ages[8]+ ages[9];
console.log(ageSum / ages.length);  //22.8

I think if I knew how to use the loop, it would be so much easier. The loop actually comes right after this lesson. I wrote the code, but I know that it’s not the best way. I cannot just add all the numbers by writing all the indexes.

While searching how I can get the average value of an array, I found out a new method reduce(). I couldn’t understand the whole document, but I could get the idea enough to apply here. Below is the code using reduce().

const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
const initialValue = 0;
const ageSum = ages.reduce(
    (previousValue, currentValue) => previousValue + currentValue, initialValue
    );
console.log(ageSum / ages.length);  //22.8

The document provided the example of adding all the elements at the top the page, so I could easily apply it. Simply put, the reduce() walks through every element of an array, executing the rule that I set. Later I’ll learn more about this method.


  • Find the range of the ages(max minus min).
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
let sortedAges = ages.sort();
let min = Math.min(...sortedAges);
let max = Math.max(...sortedAges);
console.log(max - min);  //7


  • Compare the value of (min - average) and (max - average), use abs() method.
const ages = [19, 22, 19, 24, 20, 25, 26, 24, 25, 24];
const ageSum = ages[0] + ages[1] + ages[2] + ages[3] + ages[4] + ages[5] + ages[6] + ages[7]+ ages[8]+ ages[9];
const average = ageSum / ages.length;
let sortedAges = ages.sort();
let min = Math.min(...sortedAges);
let max = Math.max(...sortedAges);
console.log(Math.abs(min - average));  //3.8000000000000007
console.log(Math.abs(max - average));  //3.1999999999999993

I know that computers aren’t always correct about its calculation, because it has limits on its memory. However, I wanted to round the number to have only one decimal point. I googled about it, and found out a new method toFixed(). It takes the number of digits as an argument, and that number of numbers will appear after the decimal point. So, if I want to print out one number after the decimal point, I can write code like toFixed(1). A thing to notice is that toFixed() returns a string.

console.log(Math.abs(min - average).toFixed(1));  //3.8
console.log(Math.abs(max - average).toFixed(1));  //3.2, it's rounded automatically.



2. Slice the first ten countries from the countries array.
console.log(countries.slice(0,10));
//(10) ['Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Australia', 'Austria']

slice() takes two parameters: the starting position and the ending position. Remember the returned value doesn’t include the ending position.


3. Find the middle country(ies) in the countries array.
if ((countries.length) % 2 === 0) {
    let middle = (countries.length / 2) - 1;
    console.log(`${countries[middle]}, ${countries[middle+1]}`);
} else {
    let middle = (countries.length - 1) / 2;
    console.log(countries[middle]);
};  //Lesotho

I used the same logic as I solved number 1. There’s only one returned value, so I can guess that countries array has odd number of items. And it sure did!

console.log(countries.length);  //193


4. Divide the countries array into two equal arrays if it is even. If countries array is not even, one more country for the first half.
if ((countries.length) % 2 === 0) {
    let middle = (countries.length / 2) - 1;
    console.log(`${countries.slice(0, middle + 1)}, ${countries.slice(middle + 1)}`);
} else {
    let middle = ((countries.length + 1) / 2) - 1;
    console.log(`${countries.slice(0, middle + 1)}, ${countries.slice(middle + 1)}`);
};

I used slice() and template literals to print out two arrays. If I put one parameter to slice(), it will slice from the parameter I put to the end of the array. Remember, the ending position isn’t included in slice()!

However, I found out that when I use template literals(``), a string is returned, not in the type of array. So I changed the code into below.

if ((countries.length) % 2 === 0) {
    let middle = (countries.length / 2) - 1;
    console.log(countries.slice(0, middle + 1), countries.slice(middle + 1));
} else {
    let middle = ((countries.length + 1) / 2) - 1;
    console.log(countries.slice(0, middle + 1), countries.slice(middle + 1));
};  //(97) [...] (96) [...]


I got another idea of shortening the code above. I can declare some variables to make the code more readable. When I pass a negative number to the first argument of slice(), it counts the elements from the end of the array, and still doesn’t include the ending index.

let firstHalf, secondHalf;

if (countries.length % 2 === 0) {
  const middle = Math.ceil(countries.length / 2);
  firstHalf = countries.splice(0, middle);
  secondHalf = countries.splice(-middle);

  console.log(firstHalf, secondHalf);
} else {
  const middle = Math.ceil(countries.length / 2) - 1;
  firstHalf = countries.slice(0, middle + 1);
  secondHalf = countries.slice(-middle);

  console.log(firstHalf, secondHalf);
}

// using 'push'
let firstHalf, secondHalf;

if (countries.length % 2 === 0) {
  const middle = Math.ceil(countries.length / 2);
  firstHalf = countries.splice(0, middle);
  secondHalf = countries.splice(-middle);

  console.log(firstHalf, secondHalf);
} else {
  const middle = Math.ceil(countries.length / 2) - 1;
  firstHalf = countries.slice(0, middle);
  secondHalf = countries.slice(-middle);
  firstHalf.push(countries[middle]);

  console.log(firstHalf, secondHalf);
}


Leave a comment