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.

Finance/Banking IdeasOrendaa wishlistTechnical Library IdeasAdaptor PatternDesign PatternsSoftware Design PrinciplesCaaS (Containers As A Service)DevOps NotesDocker Container RegistryDockerFaaS (Functions As A Service) - Serverless...IaaS (Infrastructure As A Service)KubernetesTerraformUsefulunixcommandsConcurrency vs ParallelismDistributed Service with GoDistributed System Learning NotesetcdMetrics, tracing, and loggingProtobufGoLang NotesGoLang ResourcesLearning from JPMakefileLinux NotesAanand Prasad - Creator of Fig/Docker composeMetaprogramming RubyRackDatabase SecuritySecuritySQL InjectionMVPMarket/Startup AnalysisBlue OceanHow to talk to your potential customers?How to work togetherBest way to Launch your startup (Again and Again)Business Process ModelJavascript NotesJavascript ToolsReactJSTypeScript NotesWeb APIs (Browser)Bon appétit!A note about catsTigersBackend DevelopmentBlog WishlistNotable websitesCI/CDHusky - Git commit hookConsistency is keyRedis NotesPostgresql NotesFunny / AmusingGit CLIGraphQL NotesJavascriptJSON Web Token (JWT)Move your body every dayUseful ToolsNot BehindLeslie LamportOpen AIPrivate-Public Key AuthProgramming LanguagesProject EulerRails credentialsRails Devise IntegrationRails Docker Issues and FixesRails-DockerRails NotesReproducible BuildsSemantic VersioningSoftware EngineeringSuccessChandan's TODOCraftman/EngineerYour first seed