30 Days Of JavaScript.10E
Day 10. Sets and Maps_Exercise
👟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 theset()
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 usesize
, notlength
.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