Day 10. Sets and Maps_Exercise


Level 1 / Level 2 / Level 3

👟Level 1.

const a = [4, 5, 8, 9]
const b = [3, 4, 5, 7]
const countries = ['Finland', 'Sweden', 'Norway']


1) create an empty set.
const set = new Set();


2) Create a set containing 0 to 10 using loop.
const set = new Set();
for (let i = 0; i < 10; i++) {
  set.add(i);
}

console.log(set);
// Set(10) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


3) Remove an element from a set.
const arr = [2, 8, 10, 7];
const set = new Set(arr);
set.delete(10);

console.log(set);  // Set(3) {2, 8, 7}


4) Clear a set.
const arr = ['a', 'b', 'c', 'd'];
const set = new Set(arr);
set.clear();

console.log(set);  // Set(0) {size: 0}


5) Create a set of 5 string elements from array.
const fruits = ['apple', 'mango', 'kiwi', 'peach', 'orange']
const setOfFruits = new Set(fruits);

console.log(setOfFruits);
// Set(5) {'apple', 'mango', 'kiwi', 'peach', 'orange'}


6) Create a map of countries and number of characters of a country.
const countries = ['Finland', 'Sweden', 'Denmark', 'Norway', 'IceLand'];
const mapOfCountries = new Map();

for (const ctr of countries) {
  mapOfCountries.set(ctr, ctr.length)
}

console.log(mapOfCountries);
// Map(5) {'Finland' => 7, 'Sweden' => 6, 'Denmark' => 7, 'Norway' => 6, 'IceLand' => 7}


At first I made a for...of loop like below, and it had an syntax error.

for (const ctr of countries) {
  mapOfCountries.set({ country: ctr, number of characters: ctr.length })
}

When adding elements to Map, I I should add key-value pair like (key, value), using the set() method.


👟Level 2.

1) Find a union b.
let a = [17, 21, 23, 17, 19]
let b = [18, 22, 17, 20, 21]
let c = [...a, ...b]

let C = new Set(c);

console.log(C);
// Set(7) {17, 21, 23, 19, 18, 22, 20}


2) Find a intersection b.
let a = [17, 21, 23, 17, 19];
let b = [18, 22, 17, 20, 21];

let A = new Set(a);
let B = new Set(b);

let c = a.filter((num) => B.has(num));
let C = new Set(c);

console.log(C);
// Set(2) {17, 21}


3) Find a without b.
let a = [17, 21, 23, 17, 19];
let b = [18, 22, 17, 20, 21];

let A = new Set(a);
let B = new Set(b);

let c = a.filter((num) => !B.has(num));
let C = new Set(c);

console.log(C);
// Set(2) {23, 19}


👟Level 3.

1) Print out how many languages are there in the countries object file.
const languages = countries_data.map((element) => element.languages);
const allLangs = languages.reduce((acc, cur) => [...acc, ...cur], [])
const uniqLangs = new Set(allLangs);

console.log(uniqLangs.size);  // 123

When I try to get the number of elements in Set, I should use size, not length. length is for strings and arrays.


2) Use the countries data to find the 10 most spoken languages.
  • Expected output
console.log(mostSpokenLanguages(countries, 10))
/* [
  { English: 91 },
  { French: 45 },
  { Arabic: 25 },
  { Spanish: 24 },
  { Russian: 9 },
  { Portuguese: 9 },
  { Dutch: 8 },
  { German: 7 },
  { Chinese: 5 },
  { Swahili: 4 },
  { Serbian: 4 }
]
*/

console.log(mostSpokenLanguages(countries, 3))
/* [
  { English : 91 },
  { French : 45 },
  { Arabic : 25 }
]


I have dealt with similar task at Day 9.

  • First Approach (O)
const languages = countries_data.map((element) => element.languages);
const allLangs = languages.reduce((acc, cur) => [...acc, ...cur], [])
const uniqLangs = new Set(allLangs);

const langArr = [];
for (const l of uniqLangs) {
  const count = allLangs.filter((lang) => lang === l).length;
  langArr.push({lang: l, count: count});
}
console.log(langArr);
// (123) [{lang: 'Pashto', count: 1}, {lang: 'Uzbek', count: 2},... {lang: 'Northern Ndebele', count: 1}]

const sortedLang = langSet.sort((a, b) =>
  b.count - a.count)

function mostSpokenLanguages(num) {
  const langObject = sortedLang.filter((element) =>
    sortedLang.indexOf(element) < num);
  return langObject;
}

console.log(mostSpokenLanguages(3));
/* 
  [{lang: 'English', count: 91},
  {lang: 'French', count: 45},
  {lang: 'Arabic', count: 25}]
*/

1) I first made an array of languages by using map(). Then I used reduce() and spread syntax(...) to concat all language elements in one array. Lastly, I made a unique set of languages(removed all the overlapping ones) called uniqLangs.

2) Then, I made an empty array called langArr, which is an array of objects containing language and its count. I used for loop to iterate through uniqLangs and count the times the language is used by using filter(). Then I pushed an object to the array.

3) I sorted the objects using compare function, because I’ll compare numeric values.

4) I made a function called mostSpokenLanguages that takes one parameter - a number of objects to be printed. In the expected output the function takes countries as another parameter, but I couldn’t find the array, so I modified it slightly.


  • Mistakes I’ve been through

At first, I wanted to get the same object output like an expected output, so I wrote the langArr part like below.

// (X)
const langArr = [];
for (const l of uniqLangs) {
  const count =  allLangs.filter((lang) => lang === l).length;
  langArr.push({l : count});
}
console.log(langArr);
// (123) [{l: 1}, {l: 2},... {l: 1}

It didn’t work, and it seemed like a variable cannot be placed directly in the property in an object. I tried using ${l}, but it had a syntax error too. Since l was a variable, I instead used the bracket notation([ ]) to put the language name in the place of a property in an object. I cannot use dot notation because l is a variable.


// first approach (O)
const langArr = [];
for (const l of uniqLangs) {
  const count =  allLangs.filter((lang) => lang === l).length;
  const object = {};
  object[l] = count;
  langArr.push(object);
}


// better(shortened) version (O)
const langArr = [];
for (const l of uniqLangs) {
  const count =  allLangs.filter((lang) => lang === l).length;
  langArr.push({[l] : count});
}

console.log(langArr);
// (123) [{Pashto: 1}, {Uzbek: 2},... {Northern Ndebele: 1}]

It turned out that I could push an object with a variable right away, by just putting square brackets around the variable.

However, I soon realized that I couldn’t use key-value pair comfortably. To compare the counts, I had to set the property by looping all over the uniqLangs. Also, I thought there wasn’t a way to access to the count value directly from an element.

To put a variable into another variable, use square brackets([ ]). To put a variable into a string, use a string template(${ }).


  • Another approach?

Well, I could try. I fiddled with the code to grasp the idea of the array.

console.log(langArr[0].Pashto);  // 1
console.log(Object.values(langArr[0]);  // [1]
console.log(Object.values(langArr[68]));  // [4]
console.log(Object.keys(langArr[68]));  // ['Italian']



  • Final Approach(Answer) (O)
const languages = countries_data.map((element) => element.languages);
const allLangs = languages.reduce((acc, cur) => [...acc, ...cur], [])
const uniqLangs = new Set(allLangs);

const langArr = [];
for (const l of uniqLangs) {
  const count =  allLangs.filter((lang) => lang === l).length;
  langArr.push({[l] : count});
}

const sortedLang = langArr.sort((a, b) => {
  return Object.values(b) - Object.values(a)
});

function mostSpokenLanguages(num) {
  const langObject = sortedLang.filter((element) =>
    sortedLang.indexOf(element) < num);
  return langObject;
}

console.log(mostSpokenLanguages(4));
// (4) [{English: 91}, {French: 45}, {Arabic: 25}, {Spanish: 24}]

To access to count values, I should use dot notation and Object.values() method. In langArr array, the language name is a key, and the count is a value in each object elements. So, I could just sort the elements by comparing the values of each objects.


  • Another mistake

Before I did this, which wasn’t efficient or necessary at all. I overlooked that sort() iterates all over the array. I didn’t have to use indexOf(), because sort() will automatically pass each objects as arguments.

const sortedLang = langArr.sort((a, b) => {
  return Object.values(langArr[langArr.indexOf(b)]) - Object.values(langArr[langArr.indexOf(a)]);
});


Leave a comment