JavaScript Course 7: Exercises

From WikiMLT
Revision as of 12:49, 5 July 2022 by Spas (talk | contribs) (→‎Landscape or Portrait)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Ref­er­ences

Swap­ping Vari­ables

let a = 'red';
let b = 'blue';
console.log(`a => ${a} \nb => ${b}`);
a => red 
b => blue

In or­der to swaps the val­ues of 'a' and 'b' we need a third vari­able

let buffer = a;
a = b;
b = buffer;
console.log(`a => ${a} \nb => ${b}`);
a => blue 
b => red

Max of Two Num­bers

let a = 3;
let b = 5;

function max(number1, number2) {
    return (number1 > number2) ? number1 : number2;
}
let maxNumber = max(a, b);
console.log(maxNumber);
5

Land­scape or Por­trait

function isLandscape(width, height) {
    return width > height;  // return (width > height);
}
console.log(isLandscape(680, 200));
true
console.log(isLandscape(200, 400));
false

FizzBuzz Al­go­rithm

// Divisible by 3                   => Fizz
// Divisible by 5                   => Buzz
// Divisible by 3 and 5             => FizzBuzz
// Not divisible by 3 or 5          => return the input number
// If the argument is not a number  => NaN

function fizzBuzz(input) {
    if (typeof input !== 'number') return NaN;
    if (input % 3 === 0 && input % 5 === 0) return 'FizzBuss';
    if (input % 3 === 0) return 'Fizz';
    if (input % 5 === 0) return 'Buzz';
    return input;
}
console.log(fizzBuzz(99)); console.log(fizzBuzz(100)); console.log(fizzBuzz(105)); console.log(fizzBuzz(107));
Fizz
Buzz
FizzBuzz
107

De­mer­it Points

// Speed limit = 70 km/h
// Speed <= 70 => Ok
// For every 5 km above speed linit => add 1 pont
// So: Speed < 75 => Ok
//     Speed = 75 => 1 point
//     Speed = 80 => 2 points
//     Speed = 85 => 3 points
// 12 points => License suspended

function checkSpeed(speed) {
    const speedLimit = 70;
    const kmPerPoint = 5;
    const points = Math.floor((speed - speedLimit) / kmPerPoint);
    
    if (points === 0) console.log('Ok');
    else if (points >= 12) console.log('License suspended');
    else console.log('Poinst', points);
}
checkSpeed(71); checkSpeed(77); checkSpeed(125); checkSpeed(130);
Ok
Points 1
Points 11
License suspended

Even and Odd Num­bers

function showNumbers(limit) {
    for (let i = 0; i <= limit; i++) {
        if (i % 2 === 0) console.log(i, 'EVEN');
        else console.log(i, 'ODD');
    }
}
function showNumbers(limit) {
    for (let i = 0; i <= limit; i++) {
        const message = (i % 2 === 0) ? 'EVEN' : 'ODD';
        console.log(i, message);
    }
}
showNumbers(4);
0 'EVEN'
1 'ODD'
2 'EVEN'
3 'ODD'
4 'EVEN'

Count Truthy in an Ar­ray

function countTruthy(array) {
    let counter = 0;
    for (let value of array) if (value) counter++;
    console.log(counter);
}
countTruthy([true, false, '', 'available', undefined, 1, null, 2, 'stop', 0]);
5

String Prop­er­ties of an Ob­ject

Cre­ate a func­tion that will out­put on­ly the String prop­er­ties of an Ob­ject.

function showStringProperties(obj) {
    for (let key in obj)
        if (typeof obj[key] === 'string') 
            console.log(key, obj[key]);
}
const movie = {
    title: 'a',
    releaseYear: 2018,
    rating: 4.5,
    director: 'b'
};

showStringProperties(movie);
title a
director b

Sum of Mul­ti­ples of 3 and 5

Let's as­sume there is a lim­it, for ex­am­ple 10, the mul­ti­ple of 3 are 3, 6 and 9; and the mul­ti­ples of 5 are 5 and 10.

function sumMultiplesOf3and5(limit) {
    let sum = 0;
    for (let i = 0; i <= limit; i++)
        sum += (i % 3 === 0 || i % 5 === 0) ? i : 0;
    return sum;
}
console.log(sumMultiplesOf3and5(10));
33

Grade of a Stu­dent

Grades: A[90–100], B[80–89], C[70–79], D[60–69], F[0–59].

function calculateGrade(marks) {    // marks is an Array
    let sum = 0;

    for (let mark of marks) sum += mark;
    
    let averageGrade = sum / marks.length;

    if (averageGrade < 60) return 'F';
    if (averageGrade < 70) return 'D';
    if (averageGrade < 80) return 'C';
    if (averageGrade < 90) return 'B';
    return 'A';
}

By ap­ply­ing the sin­gle re­spon­si­bil­i­ty prin­ci­ple we can di­vide this func­tion in to two small­er func­tions. Al­so we can sim­pli­fy the part that cal­cu­lates the av­er­age by the help of the .re­duce() method.

function calculateGrade(marks) {
    const average = calculateAverage(marks);

    if (average < 60) return 'F';
    if (average < 70) return 'D';
    if (average < 80) return 'C';
    if (average < 90) return 'B';
    return 'A';
}

function calculateAverage(array) {
    return array.reduce((sum, currentVal) => sum + currentVal) / array.length;
}
const marks = [80, 80, 50];
console.log(calculateGrade(marks));
C

Show Stars

function showStars(rows) {
    for (let row = 1; row <= rows; row++) {
        let pattern = '';
        for (let i = 1; i <= row; i++) {    // This is what we call a Nested Loop
            pattern = pattern + '*';
        }
        console.log(pattern);
    }
}
showStars(5);
*
**
***
****
*****

Show Primes

A prime num­bers are these which have on­ly two fac­tors 1 and it­self (prime num­ber = ця­ло чис­ло).

function showPrimes(limit) {
    for (let number = 2; number <= limit; number++) {
        let isPrime = true;
        for (let factor = 2; factor < number; factor++) {
            if (number % factor === 0) {
                isPrime = false;
                break;      // Jum out of this loop because we already know this is not Prime number
            }
        }

        if (isPrime) console.log(number);
    }
}

Ap­ply the sin­gle re­spon­si­bil­i­ty prin­ci­ple to the above func­tion.

function showPrimes(limit) {
    for (let number = 2; number <= limit; number++) 
        if (isPrime(number)) console.log(number);
}

function isPrime(number) {
    for (let factor = 2; factor < number; factor++)
        if (number % factor === 0) 
            return false;
    return true;
}
showPrimes(7);
2
3
5
7

Ad­dress Ob­ject – list all Prop­er­ties of an Ob­ject with­in a func­tion

let address = {
    street: '413-ta',
    city: 'Sofia',
    zipCode: 1715
};

function showAddress(obj) {
    for (let key in obj) 
        console.log(key, obj[key]);
}
showAddress(address);
street 413-ta
city Sofia
zipCode 1715

Fac­to­ry and Con­struc­tor Func­tions

Fac­to­ry func­tion to cre­ate the Ad­dress Ob­ject of the above ex­er­cis­es.

function cretateAddress(street, city, zipCode) {
    return {
        street,
        city,
        zipCode
    }
}
let address1 = cretateAddress('RD 41', 'Pz', '4400');
console.log(address1);
{street: 'RD 41', city: 'Pz', zipCode: '4400'}

Con­struc­tor func­tion to cre­ate the Ad­dress Ob­ject of the above ex­er­cis­es.

function Address(street, city, zipCode) {
    this.street = street;
    this.city = city;
    this.zipCode = zipCode;
}
let address2 = new Address('M4 415', 'Sf', '1715');
console.log(address2);
Address {street: 'M4 415', city: 'Sf', zipCode: '1715'}

Con­vert the Con­struc­tor func­tion to ES6 Class.

class Address {
    constructor(street, city, zipCode) {
        this.street = street;
        this.city = city;
        this.zipCode = zipCode;
    }
}
let address2 = new Address('M4 415', 'Sf', '1715');
console.log(address2);
Address {street: 'M4 415', city: 'Sf', zipCode: '1715'}

Ob­ject Equal­i­ty

class Address {
    constructor(street, city, zipCode) {
        this.street = street;
        this.city = city;
        this.zipCode = zipCode;
    }
}
let address1 = new Address('a', 'b', 'c');
let address2 = new Address('a', 'b', 'c');
let address3 = address1;

Func­tion to test whether the ob­jects are equal.

function areObjectsEqual(obj1, obj2) {
    if (Object.keys(obj1).length === Object.keys(obj1).length) {
        for (let key in obj1)
            if (obj1[key] !== obj2[key])
                return false;
        return true;
    }
    return false;
}
console.log(areObjectsEqual(address1, address2));
true

Func­tion to test whether the ob­jects are same – re­fer to the same ob­ject in the mem­o­ry.

function areObjectsSame(obj1, obj2) {
    return obj1 === obj2;
}
console.log(areObjectsEqual(address1, address2));
false
console.log(areObjectsEqual(address1, address3));
true

Blog Post – Train­ing for Ob­ject Lit­er­al Syn­tax

const post = {
    title: "Post title",
    body: "Post body...",
    author: "Post author",
    views: 153,
    comments: [
        {author: "Comment 1 author", body: "Comment 1 body..."},
        {author: "Comment 2 author", body: "Comment 2 body..."}
    ],
    isLive: true
};

Con­struc­tor Func­tion for Blog Post Ob­jects

function Post(title, body, author) {
    this.title = title;
    this.body = body;
    this.author = author;
    this.views = 0;
    this.comments = [];
    this.isLive = false;
}
const post1 = new Post('Title 1', "Body of title 1...", 'SZS');
console.log(post1);
Post {title: 'Title 1', body: 'Body of title 1...', author: 'SZS', views: 0, comments: Array(0), isLive: false}

Price Range Ob­ject

let priceRanges = [
    {label: "$", tooltip: "Inexpensive", minPerPerson: 0, maxPerPerson: 10},
    {label: "$$", tooltip: "Moderate", minPerPerson: 11, maxPerPerson: 20},
    {label: "$$$", tooltip: "Expensive", minPerPerson: 21, maxPerPerson: 50}
];

let restaurants = [
    {name: 'a', averagePerPerson: 5},
    {name: 'b', averagePerPerson: 15},
    {name: 'c', averagePerPerson: 25}
];

// We can create a filter as intersection of these 2 objects

Ar­ray from Range

function arrayFromRange(min, max) {
    const output = [];
    for (let i = min; i <= max; i++) output.push(i);
    return output;
}
const numbers = arrayFromRange(-7, 4);
console.log(numbers);
(12) [-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4]

In­cludes in Ar­ray

Cre­ate a re­place­ment func­tion for the .in­cludes() method.

function includes(array, searchedElement) {
    for (let element of array) 
        if (element === searchedElement)
            return true;
    return false;
}
const numbers = [1, 2, 3, 4];
console.log(includes(numbers, 2), includes(numbers, 5));
true false

Ex­cept – Ex­clude el­e­ment from an ar­ray

function  except(array, excluded) {
    const output = [];
    for (let element of array) {
        if (!excluded.includes(element)) 
            output.push(element);
    }
    return output;
}
const numbers = [1, 2, 3, 4, 1, 1, 7, 1, 5, 1];
const output = except(numbers, [1, 2, 7]);
console.log(output);
(3) [3, 4, 5]

Mov­ing an El­e­ment in an Ar­ray

function  move(array, index, offset) {
    const newPossition = index + offset;
    
    if (newPossition >= array.length || newPossition < 0) {
        console.error('Invalid offset.');
        return;
    }
    
    const output = [...array];

    // const elementToMove = output[index]; output.splice(index, 1);
    // The above lines could be replaced by the follow expression, because the .splice() method 
    // modifies the original array and returns an array of the removed elements [we need the first]
    const elementToMove = output.splice(index, 1)[0];
    output.splice(newPossition, 0, elementToMove);

    return output;
}
const numbers = [1, 2, 3, 4];
const output = move(numbers, 3, -2);
console.log(output);
(4) [1, 4, 2, 3]

Count Oc­cur­rences of an Val­ue in an Ar­ray

By us­ing for.. of.. loop.

function  countOccurances(array, searchedElement) {
    let count = 0;
    for (let element of array)
        if (element == searchedElement)
            count++;
    return count;
}

By us­ing .re­duce() method;

function  countOccurances(array, searchedElement) {
    return array.reduce((count, currentValue) => count += (currentValue === searchedElement) ? 1 : 0, 0);
}
const numbers = [1, 2, 3, 1, 2, 4, 1, 5, 4, 2, 3, 3, 8, 1, 9];
const output = countOccurances(numbers, 2);
console.log(output);
3

Get max Oc­cur­rences of an Val­ue in an Ar­ray

By us­ing for.. in.. loop.

function  getMax(array) {
    if (array.length === 0) return undefined;

    let max = array[0];

    for (let i = 1; i < array.length; i++)
        if (array[i] > max)
            max = array[i];
            
    return max;
}

By us­ing for.. of.. loop.

function  getMax(array) {
    let max = 0;
    
    for (let element of array)
        if (element > max)
            max = element;
            
    return (max) ? max : undefined;
}

By us­ing .re­duce() method.

function  getMax(array) {
    if (array.length === 0) return undefined;
    return array.reduce((max, currentValue) => (max > currentValue) ? max : currentValue);
}
function  getMax(array) {
    return array.reduce((max, currentValue) => (max > currentValue) ? max : currentValue, undefined);
}
const numbers = [1, 2, 3, 1, 2, 4, 11, 5, 4, 2, 3, 3, 8, 1, 9];
const max = getMax(numbers);
console.log(max);
11

Sort an Ar­ray of Movie Ob­jects

Out­put all the movies in 2018 with rat­ing > 4, sort them by their rat­ing in de­scend­ing or­der and dis­play on­ly ti­tle prop­er­ty on the con­sole.

const movies = [
    {title: 'a', year: 2018, rating: 4.5},
    {title: 'b', year: 2018, rating: 4.7},
    {title: 'c', year: 2018, rating: 3},
    {title: 'd', year: 2017, rating: 4.5}
];

By us­ing for.. of.. loop and if con­di­tion.

function getMovies(movies = [], ofYear = 2018, minRating = 4) {
    const output = [];
    for (let movie of movies) {
        if (movie.year === ofYear && movie.rating > minRating)
            output.push(movie.title);
    }
    return output.sort().reverse();
}
const titles = getMovies(movies, 2018, 4);

By us­ing .fil­ter(), .sort(), re­verse() and map() meth­ods.

const titles = movies
    .filter(movie => (movie.year === 2018 && movie.rating > 4))
    .sort((a, b) => a.rating - b.rating)
    .reverse()
    .map(movie => movie.title);

By re­vers­ing the or­der with­in the .sort() method, and skip .re­verse() method.

const titles = movies
    .filter(movie => (movie.year === 2018 && movie.rating > 4))
    .sort((a, b) => b.rating - a.rating)
    .map(movie => movie.title);
console.log(titles);
(2) ['b', 'a']

Sum of Ar­gu­ments

In this ex­er­cise we will cre­ate a func­tion that re­turns the sum of its ar­gu­ments. They could be passed as an ar­ray or as sep­a­rate ar­gu­ments.

By us­ing rhe Ar­gu­ments spe­cial ob­ject and a for.. of.. loop.

function sumArguments() {
    let args = [];
    let sum = 0;

    if (Array.isArray(arguments[0])) args = [...arguments[0]];
    else args = [...arguments];

    for (let i of args) sum += i;
         
    return sum;
}
const sumArray = sumArguments([1, 2, 3, 4]);
const sumArgs = sumArguments(1, 2, 3, 4);
console.log(sumArray, sumArgs);
10 10

By us­ing the Ar­gu­ments spe­cial ob­ject and the .re­duce() method.

function sumArguments() {
    let args = [];

    if (Array.isArray(arguments[0])) args = [...arguments[0]];
    else args = [...arguments];

    return args.reduce((sum, currentValue) => sum + currentValue);
}
const sumArray = sumArguments([1, 2, 3, 4]);
const sumArgs = sumArguments(1, 2, 3, 4);
console.log(sumArray, sumArgs);
10 10

By us­ing the …Rest op­er­a­tor and the .re­duce() method.

function sumRest(...args) {
    if (args.length === 1 && Array.isArray(args[0])) args = [...args[0]];
    return args.reduce((sum, currentValue) => sum + currentValue);
}
const sumArray = sumRest([1, 2, 3, 4]);
const sumArgs = sumRest(1, 2, 3, 4);
console.log(sumArray, sumArgs);
10 10

Area of Cir­cle – Us­ing a Get­ter Method

const circle = {
    radius: 2,
    get area() {
        return this.radius * this.radius * Math.PI;
    }
};
console.log(circle.area);
circle.radius = 4;
console.log(circle.area);
12.566370614359172
50.265482457436690

Er­ror Han­dling

function countOccurrences(array, searchElement) {
    if (!Array.isArray(array)) 
        throw new Error('Invalid array!');

    return array.reduce((accumulator, current) => {
        return (current === searchElement) ? accumulator + 1 : accumulator + 0;
    }, 0);
}
const numbers = [1, 2, 3, 1, 4];
try {
    const count = countOccurrences(numbers, 1);
    console.log(count);
}
catch (e) {
    console.log(e.message);
}
2
const numbers = false; // or anything else different from array
try {
    const count = countOccurrences(numbers, 1);
    console.log(count);
}
catch (e) {
    console.log(e.message);
}
Invalid array!