Javascript Notes

Javascript refresher

let name = "Chandan In JS";
console.log(name);

let firstName = "Chandan";
let lastName = "Jhunjhunwal";

const interestRate = 0.1;
// interestRate = 1;
console.log("Interest rate: ", interestRate)

// Primitive Type Variables:
// String
// Number
// Boolean
// undefined
// null
let str = "Hi"; // String literal
let age = 37; // Number literal
let isApproved = false; // Boolean Literal
let undefVariable = undefined;
let nullVariable = null;

console.log("typeof str: ", typeof str)
str = 10;
console.log("typeof str: ", typeof str)
console.log("typeof isApproved: ", typeof isApproved)
console.log("typeof isApproved: ", typeof isApproved)
console.log("typeof undefVariable: ", typeof undefVariable)
console.log("typeof nullVariable: ", typeof nullVariable)

// Reference types
// Object
// Array
// Functions

// Object
let person = {
    firstName: "Chandan",
    lastName: "Jhunjhunwal",
    age: 37
};

for (let key in person) {
    console.log("Key:", key)
    console.log("Value", person[key])
}

console.log(person);
console.log(person.firstName);
console.log(person['lastName']);
let selection = "age";
console.log(person[selection]);


console.log("// Array")
let selectedColors = ['red', 'blue', 1, null, false]; // Array Literals
console.log(selectedColors);
selectedColors[5] = 'green';
console.log(selectedColors);
console.log("typeof Array selectedColors", typeof selectedColors)
console.log("Array selectedColors length: ", selectedColors.length)

for(let index in selectedColors) {
    console.log("Element at index", index, selectedColors[index])
}

for(let color of selectedColors) {
    console.log("Color is", color)
}

selectedColors.forEach(color => console.log(color))

selectedColors.forEach((color, index) => console.log(color, index))

// Functions
function greet(firstName, lastName){
    console.log("Hello", firstName, lastName);
}
greet("Chandan", "Jhunjhunwal");
greet("Darsh", "Jhunjhunwal")
greet("Mary")

function square(number){
    return number * number;
}

let number = square(2);
console.log(number);

// Strict Equality (Same type and same value)
console.log("1 === 1", 1 === 1);
console.log("'1' === 1", '1' === 1);

// Loose equality - Same value
console.log("1 == 1", 1 == 1);
console.log("'1' == 1", '1' == 1);
console.log("true == 1", true == 1);

// Falsy (false)
// undefined
//  null
//  0
// false
// ''
// NaN

// Anything, which is not Falsy -> Truthy

let userColor = undefined;
let defaultColor = "Blue";
let currentColor = userColor || defaultColor;

console.log(currentColor)

// 1 = 00000001
// 2 = 00000010
// 1 | 2 = 00000011
// 1 & 2 = 00000000
console.log(1 | 2);
console.log(1 & 2);

// Read, Write, Execute
// Read permission:    00000100
// Write permission:   00000010
// Execute Permission: 00000001
let readPermission = 4;
let writePermission = 2;
let executePermission = 1;

let myPermission = 0;
// Assign read and write permission
myPermission = myPermission | readPermission | writePermission
console.log(myPermission)

// Check for permission
let doIHaveReadPermission = (myPermission & readPermission) ? 'Yes' : 'No'
console.log(doIHaveReadPermission)

for(let i = 1; i <= 5; i++ ){
    console.log("Loop index", i)
}

let whileIndex = 5;
while(whileIndex > 0) {
    if (whileIndex % 2 == 0) console.log("while even index", whileIndex);
    whileIndex--;
}

// Function for max of an array

function maxOfArray(array){
    let maxNum = array[0];
    for(let num of array) {
        maxNum = maxNum > num ? maxNum : num
    }
    return maxNum
}

console.log(maxOfArray([1,1000, 4,100,4,5]))

function isLandscape(width, height) {
    return width > height
}

function fizzBuzz(n){
    if (typeof n !== 'number'){
        console.log(NaN)
    }
    for(let i = 1; i <= n; i++) {
        let div_by_2 = (i % 2 === 0);
        let div_by_3 = (i % 3 === 0);
        if (div_by_2 && div_by_3){
            console.log("FizzBuzz")
        } else if (div_by_2){
            console.log("Fizz")
        } else if (div_by_3){
            console.log("Buzz")
        } else {
            console.log(i)
        }
    }
}
fizzBuzz(1)
fizzBuzz(null)

// Speed Limit = 70
// Anything below 75 = OK
// For every extra 5 speed = 1 points
// If the speed exceeds 120 = license suspended
function speedLimit(speed) {
    const limit = 70;
    if (speed < (limit+5)) {
        console.log('OK')
        return
    }
    points = Math.floor((speed - limit)/5)
    if (points < 12) {
        console.log("Points:", points)
    } else {
        console.log("License suspended!")
    }
}

speedLimit(70);
speedLimit(74);
speedLimit(75);
speedLimit(110);
speedLimit(120);
speedLimit(170);


function printTruthy(array) {
    for(let elem of array) {
        if (elem) {
            console.log("Truthy:", elem)
        } else {
            console.log("Falsy", elem)
        }
    }
}

printTruthy([1, '', null, "HI", undefined, 10.10, NaN])

function showStringProperties(obj){
    for(let key in obj) {
        if (typeof obj[key] === 'string') {
            console.log(key, ":", obj[key])
        }
    }
};

const movie = {
    title: "The Pursuit of Happiness!",
    year: 2006,
    Director: "Gabriele Muccino",
    actor: "Will Smith",
    duration: 117
};

showStringProperties(movie)

function getSumOfMultiplesThreeFive(limit){
    let sum = 0;
    for(let i = 1; i <= limit; i++) {
        if (i%3 === 0 || i%5 === 0){
            // console.log(i)
            // console.log(sum)
            sum += i
            // console.log(sum)
        }
    }
    console.log(sum)
};

getSumOfMultiplesThreeFive(10)


function showStars(n){
    let str = ''
    for (let i = 1; i <= n; i++){
        str += '*'
        console.log(str)
    }
}

showStars(10)


// Object
const circle = {
    radius: 10,
    location: {
        x: 1,
        y: 2
    },
    isVisible: true,
    draw: function (){
        console.log('draw')
    }
}

circle.draw();

// Factory functions
// Camel notation
function createCircle(radius, location, isVisible){
    return {
        radius: radius,
        location: location,
        isVisible: isVisible,
        draw: function (){
            console.log('draw')
        }
    }
}
// A better way to write same thing
function createCircleClean(radius, location, isVisible){
    return {
        radius, //equivalent to radius: radius
        location,
        isVisible,
        draw(){ // equivalent to draw: function(){ console.log('draw')}
            console.log('draw')
        }
    }
}

const circle1 = createCircleClean(1, {x: 10, y:100}, true)
const circle2 = createCircleClean(100, {x: 1, y:10}, false)

console.log(circle1);
circle1.draw();
console.log(circle1.radius);
console.log(circle1.location);
console.log(circle1.radius);
console.log(circle2);

// Iterating through objects
console.log("// Iterating through objects")
for(let key in circle) {
   console.log(key)
}

// for of loop can only be used with the objects having 'iterator' method
for(let key of Object.keys(circle)){
    console.log(key)
}

for(let entity of Object.entries(circle)){
    console.log(entity)
}

if ('radius' in circle) { console.log("Yes")}

// Cloning object
const anotherCircle = {}
for(let key in circle) {
    anotherCircle[key] = circle[key]
}

console.log(anotherCircle)
// another way of cloning
const anotherClone = Object.assign({}, circle)
console.log(anotherClone)
// another way of cloning using spread operator
const yetAnotherClone = { ...circle }
console.log(yetAnotherClone)


// Constructor function
// Pascal notation

function Circle(radius, location, isVisible){
    this.radius = radius;
    this.location = location;
    this.draw = function(){
        console.log('draw')
    }
}

const circle3 = new Circle(10, {x: 10, y: 10}, true)

console.log(circle3)
circle3.draw()

// NOTE: Factory function and constructor function, both are meant to create objects
// The only difference is convention


// Dynamic property of object

const squareShape = {
    side: 10
};

// Following reassignment to new object will not work as squareShape is defined as "const"
// squareShape = {};

console.log(squareShape);
// Properties can be added dynamically
squareShape.area = squareShape.side**2
console.log(squareShape);
// A function can be added dynamically as property
squareShape.draw = function(){
    console.log('draw');
}
console.log(squareShape);
squareShape.draw();

// A property can be deleted
delete squareShape.area;
delete squareShape.side;
console.log(squareShape)

// Every object has "constructor" property, which is actually used to create that object
//  Javascript internally defines contructor for each object, unless an explicit contructor is defined.
// Example above "Circle" is explicit contructor
//
// circle2.constructor
// ƒ Object() { [native code] }
// circle3.constructor
// ƒ Circle(radius, location, isVisible){
//     this.radius = radius;
//     this.location = location;
//     this.draw = function(){
//         console.log('draw')
//     }
// }


// In JS, functions are objects

const CustomCircle = new Function('radius', `
    this.radius = radius;
    this.draw = function(){
        console.log('draw')
    }
`)

const myCircle = new CustomCircle(1);
const myNewCircle = CustomCircle.call({}, 10); // TODO: Logs undefined
console.log(myCircle)
console.log(myNewCircle)


// Primitives are copied by value
// Objects are copied by reference.

let myNumber = 10;

function incrementNum(myNumber){
    myNumber++;
}
incrementNum(myNumber);
console.log(myNumber); // logs 10

let numObject = {value: 10};
function incrementObjNum(numObject){
    numObject.value++
}
incrementObjNum(numObject);
console.log(numObject) // logs value: 11


console.log("// String ")

const myStr = 'hi';
console.log(typeof myStr); // 'string'

const anotherStr = new String('hi');
console.log(typeof anotherStr) // 'object'


console.log("// Template Literals")
let mailMsg = "Hi " + firstName + " " + lastName + "\n"
console.log(mailMsg);

// Using template literals
let tMaillMsg =
`Hi ${firstName} ${lastName},

Thank you for subscribing to my newsletter.

Cheers,
Chandan`

console.log(tMaillMsg)

// Address contstructor
class Address {
    constructor(street, city, zipcode) {
        this.street = street;
        this.city = city;
        this.zipcode = zipcode;
    }
}

// Factory function
function createAddress(street, city, zipcode){
    return {
        street,
        city,
        zipcode
    }
}

// const yetAnotherCreateAddress = new function ("street", "city", "zipcode", `
// this.street = street;
// this.city = city;
// this.zipcode = zipcode;
// `)

const address = new Address("Handewadi", "Pune", 411028)
const anotherAddress = createAddress("Station Road", "Sakri", 847239)

function showAddress(address){
    for(let entry of Object.entries(address)){
        console.log(entry)
    }
}

showAddress(address)
showAddress(anotherAddress)

function equalAddress(address1, address2) {
    if (JSON.stringify(Object.keys(address1)) !== JSON.stringify(Object.keys(address2))){
        return false
    }
    let equal = true
    for(let key in address1) { // but address2 can have additional keys or some keys from address1 might have been deleted.
        if (address1[key] != address2[key]){
            equal = false
            break
        }
    }
    return equal
}

console.log(equalAddress(address, anotherAddress))
console.log(equalAddress(anotherAddress, anotherAddress))

function sameAddress(address1, address2) {
    return (address1 === address2)
}

console.log(sameAddress(address, anotherAddress))
console.log(sameAddress(anotherAddress, anotherAddress))


class BlogPost {
    constructor(title, body, author, views, comments, isLive) {
        this.title = title;
        this.body = body;
        this.author = author;
        this.views = views || 0;
        this.comments = comments || [];
        this.isLive = isLive || false;
    }
}

class Comment{
    constructor(author, body) {
        this.author = author;
        this.body = body
    }
}

let newPost = new BlogPost(
    "First Post",
    "Post body",
    "Chandan"
)

let oldPost = new BlogPost(
    "First Post",
    "Post body",
    "Chandan",
    100,
    [new Comment('chandan', 'Hi')],
    true
)

console.log(newPost)
console.log(oldPost)

// Array
// Combine Array
a1 = [1,2,3,4]
a2 = [5,6,78]

const combined = [...a1, ...a2]

const course_list = [
    {id: 1, name: "Node.JS"},
    {id: 2, name: "Javascript"},
    {id: 3, name: "GoLang"},
    {id: 4, name: "Ruby"}
]

console.log(course_list)

course_list.sort((c1, c2) => {
    const name1 = c1.name.toUpperCase();
    const name2 = c2.name.toUpperCase();
    if (name1 < name2) return -1
    if (name2 > name1) return 1
    return 0
})

console.log(course_list) // It'll modify the original object, so any earlier reference to course_list will also see this mutation

const arr = [1,2,3,5]

const allPositive = arr.every(element => element > 0)
console.log(allPositive)

const arr1 = [1,23,-1]
const someNegative = arr1.some(element => element < 0)
console.log(someNegative)

const arr2 = [1,2,-1,4,5]
const filteredArr = arr2.filter(element => element > 0)
console.log(filteredArr)

const items = filteredArr.map(element => "<li>" + element + "</li>")
const html = "<ul>" + items.join('') + "</ul>"
console.log(items)
console.log(html)

console.log(items.map (element => ({value: element})))

// Chainable
const polishedItems = arr2
    .filter(ele => ele > 0)
    .map(ele => ({value: ele}))
    .filter(ele => ele.value > 3)

console.log("polished items:", polishedItems)

const sum = arr2.reduce((accumulator, current_value) => {
    return accumulator + current_value
}, 0)

console.log(sum)

console.log("// Array excercise 1")
const numbers = arrayFromRange(-10, 5)

console.log(numbers);

function arrayFromRange(min, max) {
    let array = []
    for(let i = min; i <= max; i++) {
        array.push(i)
    }
    return array
}

console.log("// Array excercise 2")
console.log(customIncludes(numbers, 5))

function customIncludes(array, searchElem) {
    for(i=0; i < array.length; i++){
        if (array[i] === searchElem) return true
    }
    return false
}

console.log("// Array excercise 3")
const arr_ex3 = [1,2,3,4,5,6,7,1,1,1]

console.log(arr_ex3)
console.log(excludes(arr_ex3, [1,2,3,4]))

function excludes(input_array, exclude_array) {
    const resulting_array = []
    for(let elem of input_array) {
        if (exclude_array.indexOf(elem) < 0){
            resulting_array.push(elem)
        }
    }
    return resulting_array
}

console.log("// Array excercise 4")
const arr_ex4 = [1,2,3,4]
const output = move(arr_ex4, 1, -1); // Move element at index 1 to index 3

console.log(output)

function move(input, elem_index, offset) { // offset is new index
    if(elem_index >= input.length){
        console.error("Invalid element index")
        return
    }
    if(elem_index+offset < 0){
        console.error("Invalid offset")
        return
    }
    const output = [];
    // when offset positive
    // all elements before elem_index will remain as it is
    // all elements after  elem_index + offset will remain same
    // all elements between elem_index and elem_index + offset will shift left by 1
    // element at elem_index+offset will be input[elem_index]
    if (offset >= 0) {
        input.forEach((elem, index) => {
            if(index < elem_index) {
                output.push(elem)
            } else if (index > elem_index + offset) {
                output.push(elem)
            } else if ((index >= elem_index) && (index < elem_index + offset)) {
                output.push(input[index+1])
            } else if (index === elem_index + offset){
                output.push(input[elem_index])
            }
        })
    } else {
        // when offset negative
        // all elements before elem_index + offset will remain as it is
        // all elements after elem_index will remain as it is
        // all elements after elem_index + offset and before elem_index will shift right by 1
        // element at elem_index+offset will be input[elem_index]
        input.forEach((elem, index) => {
            if(index < (elem_index+offset)) {
                output.push(elem);
            } else if (index > elem_index) {
                output.push(elem)
            } else if ((index > elem_index+offset) && (index <= elem_index)) {
                output.push(input[index-1])
            } else if (index === elem_index + offset) {
                output.push(input[elem_index])
            }
        })
    }

    // Another solution
    const output_1 = [...input];
    const element = output_1.splice(elem_index, 1)[0]
    output_1.splice(elem_index+offset, 0, element)


    return output


    // let output_array = [];
    // let new_position = elem_index + offset
    // let original_array = [...input]
    // // delete the element from array
    // shifting_elem = input.splice(elem_index, 1)
    // // new_position > elem_index?
    // for(let i = 0; i < original_array.length; i++ ){
    //     // Anything before new_position should remain as it is
    //     // Everything after new position should be shifted
    //     if (i == new_position) {
    //         output_array = output_array.concat(shifting_elem)
    //     } else if (i < elem_index) {
    //         output_array.push(original_array[i])
    //     } else {
    //         output_array.push(original_array[i+1])
    //     }
    // }
    // // push all elements to output until reach at elem_index
    // // copy elem_index in temp variable and start pushing next elements upto elem_index + offset - 1
    // // push the temp variable at elem_index+offset
    // // push remaining elements to output
    // let temp;
    // input.forEach((elem, index) => {
    //     if (index < elem_index) {
    //         output_array.push(elem)
    //     } else if (index == elem_index) {
    //         temp = elem;
    //     } else if (index <= (elem_index+offset-1)) {
    //         output_array.push(input[index])
    //     } else if (index === elem_index+offset) {
    //         output_array.push(temp)
    //     } else if (index > elem_index+offset){
    //         output_array.push(elem)
    //     }
    // })
    // return output_array
}


console.log("// Count occurence Array ex 5")

const num_ex5 = [1,2,3,4,4,5]
const count_ex5 = countOccurences(num_ex5, 4);

console.log(count_ex5);
console.log(countOccurencesReduce(num_ex5, 4));

function countOccurences(input, searchElement){
    let count=0;
    for(let num of input){
        if (num === searchElement) {
            count++;
        }
    }
    return count
}

function countOccurencesReduce(input, searchElement){
    return input.reduce((count, elem) => {
        const occured = (elem === searchElement) ? 1 : 0;
        return count + occured;
    }, 0
    )
}

console.log("//Get Max of an array ex6")
const num_ex6 = [1,2,3,4,2,100]

const max_ex6 = getMax(num_ex6)

console.log(max_ex6)

function getMax(input){
    if (input.length === 0) {
        return undefined;
    }
    return input.reduce((accumulator, elem) => {
        return accumulator > elem ? accumulator : elem
    }, input[0])
}

console.log("//Movies ex7")
// All movies in 2018 with rating > 4
// Sort them by rating desc
// pick their title
const movies = [
    {
        title: 'c',
        year: 2019,
        rating: 4.5
    },
    {
        title: 'd',
        year: 2028,
        rating: 4
    },
    {
        title: 'e',
        year: 2018,
        rating: 5
    },
    {
        title: 'b',
        year: 2018,
        rating: 4
    },
    {
        title: 'a',
        year: 2018,
        rating: 4.5
    }
]

console.log(pickMoviesInYear(movies, 2018, 4));

function pickMoviesInYear(movies, year, rating) {
    // Solution 1
    // const movies_in_year = []
    // for(let movie of movies){
    //     if(movie.year === year && movie.rating >= rating){
    //         movies_in_year.push(movie)
    //     }
    // }

    // return movies_in_year.sort((m1, m2) => {
    //     const m1Title = m1.title.toUpperCase();
    //     const m2Title = m2.title.toUpperCase();

    //     if (m1Title < m2Title) return -1;
    //     if (m1Title > m2Title) return 1;
    //     return 0;
    // }).map(movie => movie.title)
    // Solution 2:
    const titles = movies
        .filter(m => m.year === year && m.rating >= rating)
        .sort((m1, m2) => m1.rating - m2.rating)
        .reverse()
        .map(m => m.title)
    return titles
}

console.log("// Functions")
// Function declaration
// Can be called before this function declaration
// "Hoisting" = moving the function declaration to the top of file.
function walk(){
    console.log('walk')
}

// Anonymous Function expressions
// Can be called only after the below expression, as run is a variable
let run = function(){
    console.log('run');
};

let running = run;
run();
running();

// Named Function expressions
let runNamed = function runNamed (){
    console.log('run');
};

// "arguments" inside a function

function sumAll(){
    let total = 0;
    for(let num of arguments) {
        total += num
    }
    return total
}

console.log(sumAll(1,2,3,4,5,6,7))

// Rest operator/parameter
function sumAllRestOperator(...args){
    return args.reduce((a,b) => a+b)
}

console.log(sumAllRestOperator(1,2,3,4,5,6,7))

// Rest parameter must be last parameters in a function definition
// i.e. after explicit arguments, rest all are rest parameters, that's why it's called rest operator.
function finalPrice(discount, ...prices){
    return prices.reduce((a,b) => a+b)*(1-discount)
}

console.log(finalPrice(0.1, 100,200))

// Default arguments
// IMPORTANT: If a default value is provided for an argument, any argument after that should also have default value
// else the defaulted argument will have to be passed as undefined to pass next argument without default value
function calculateInterest(principle, interest = 3.5, duration = 5){
    return principle*(interest/100)*duration
}

console.log(calculateInterest(100))
console.log(calculateInterest(100, 5))
console.log(calculateInterest(100, 5 , 10))

function acheck(p, i = 10, j){
    return p*i*j
}
// If we don't want to pass value of i, then pass it as undefined.
acheck(10, undefined, 10)

console.log("//Getter/Setter")
const human = {
    firstName: "Chandan",
    lastName: "Jhunjhunwal",
    get fullName(){
        return `${this.firstName} ${this.lastName}`
    },
    set fullName(value) {
        if (typeof value !== 'string'){
            throw new Error("Please pass a valid string");
        }
        const parts = value.split(' ');
        if (parts.length !== 2) {
            throw new Error("Please enter first and last name");
        }
        this.firstName = parts[0]
        this.lastName = parts[1]
    }

}

human.fullName = "Darsh J"

// try {
//     human.fullName = null;
// }
// catch (e){
//     alert(e);
// }

// try {
//     human.fullName = ''
// }
// catch (e){
//     alert(e);
// }
// try {
//     human.fullName = 'Chandan'
// }
// catch (e){
//     alert(e);
// }
console.log(human)


console.log("//var vs let")
// Var defines a variable available within whole function, where as let is block scoped
function varLet(){
    for(var i = i; i <=5; i++){
        if(true) {
            var j = 100;
        }
    }
    console.log(i);
    console.log(j)
}

varLet();
// Defines window level variable
var windowLevel = 'red';

// this(->)
// method -> obj
// function -> global ("window" in browser, "global" in node)
const myObj = {
    id: 1,
    cat(){
        console.log(this)
    }
}

myObj.cat();

myObj.dog = function(){
    console.log(this)
}
myObj.dog();

function playVideo(){
    console.log(this)
}
playVideo();

class Video {
    constructor(title) {
        this.title = title;
        console.log(this)
    }
}

const v = new Video('video title') // here -> refers to {} as new keyword is used

const video = {
    id: 1,
    tags: ['drama', 'violence', 'drug'],
    showTags(){
        const self = this;
        this.tags.forEach(function(tag){ // this function is anonymous function, so "this" is "window". Need to pass "this" as last argument
            console.log(this.id, tag);
            console.log(self.id, tag)
        }, this)
    }
}

video.showTags();

// Changing this for global function

function playVideoFn(a,b){
    console.log(this);
}
// call access first argument for this and other arguments as next arguments
playVideo.call({name: "Chandan"}, 1,2)
// apply access first argument for this and other arguments in an array
playVideo.apply({id: 100}, [100,200])
// bind binds the argument object to returned function permanently
const fn = playVideo.bind({obj_id: 1})
fn()
// bind(ed) function can be called directly
playVideo.bind({x: 100})();

const video1 = {
    id: 1,
    tags: ['drama', 'violence', 'drug'],
    showTags(){
        const self = this;
        this.tags.forEach(function(tag){ // this function is anonymous function, so "this" is "window". Need to pass "this" as last argument
            console.log(this.id, tag);
        }.bind(this))
    }
}
video1.showTags();

// ES6 using arrow function - arrow function keeps the context of "this"
const video2 = {
    id: 1,
    tags: ['drama', 'violence', 'drug'],
    showTags(){
        this.tags.forEach(tag => console.log(this.id, tag))
    }
}
video2.showTags();


// functions excercise 1
const sumAllVersatile = function(...args){
    if(args.length === 1 && Array.isArray(args[0])){
        args = [...args[0]] //OR
        // args = args[0]
    }
    return args.reduce((a,n) => a+n)
}

console.log(sumAllVersatile(1,2,3,4));
console.log(sumAllVersatile([1,2,3,4]));

// functions excercise 2
// circle.radius = 2 - Read and Write
// circle.area - Read only

const circle_ex2 = {
    radius: 1,
    get area(){
        return Math.PI*this.radius*this.radius
    }
}

console.log(circle_ex2);
console.log(circle_ex2.radius);
console.log(circle_ex2.area);

circle_ex2.radius = 2;
console.log(circle_ex2);
console.log(circle_ex2.radius);
console.log(circle_ex2.area);

// functions excercise 3
try {
    const numbers_ex3 = [1,2,3,4,5, 1]

    // const count_ex3 = countOccurencesEx3(numbers_ex3, 1);
    const count_ex3 = countOccurencesEx3(true, 1);
    console.log(count_ex3);
}

catch (e){
    console.log(e)
}

function countOccurencesEx3(array, searchElem){
    if(!Array.isArray(array)){
        throw new Error("Please pass array as first argument")
    }
    return array.reduce((count, elem) => {
        const occured = (elem == searchElem) ? 1 : 0;
        return count += occured;
    }, 0);
}

This is a sapling 🌱 in my digital garden 🏡.

Notes mentioning this note

There are no notes linking to this note.


Here are all the notes in this garden, along with their links, visualized as a graph.