# HackerRank - 10 Days JavaScript Challenge

## Basic JavaScript&#x20;

#### Data Types and Manipulation

* parseInt() - make integer
* parseFloat() - make float
* String() - make string, strings can be concatenated using +

#### Loops

* for & while loops
* do - while loops
* for - in loops
* for - of loops

For Loop

```javascript
//for (initialize; condition to be true to execute; final expressions) {
//   code;
//}
function main(parameter){
    for (var i = 1; i<= parameter; i++){
        console.log("Go on");
    }
}
```

While Loop

```javascript
function main(input) {
    var i = 1;
    while (i <= input) {
        process.stdout.write(i + " ");
        i++;
    }
}
```

Do-while Loop

```javascript
// Executes until specified condition is false, same as while loop la
function main(parameter){
    var i = 1;
    do { console.log(i +" hi");
    i++;
    } while (i <=parameter);
}
```

For In Loop

```javascript
// Iterates over name of each enumerable property in object, executes
for (var variable in object) {
    // insert code that uses variable here
}
```

For Of Loop

```javascript
// Iterates the VALUE of each property in the structure (array or letter in word)
function main(input) {
    // Split the words read as input into an array of words
    var array = input.split(new RegExp("[ \n]+"));
    console.log(array);

    // Print each of its elements on a new line
    for (let value of array) {
        console.log(value);
    }
}
// EXAMPLE 2
let actress = new Map([
    ["firstName", "Julia"],
    ["lastName", "Roberts"],
    ["dateOfBirth", "October 28, 1967"],
    ["nationality", "American"],
    ["firstMovie", "Satisfaction"]
]);

// Print each Key-Value pair in the map
for (let info of actress) {
    console.log(info);
}

// Print each Key and Value as "Key: Value"
console.log();
for (let info of actress) {
    console.log(info[0] + ": " + info[1]);
}
```

### Loop over char of String, Extract Vowels & Consonants

1. First, print each *vowel* in  on a new line. The English vowels are *a*, *e*, *i*, *o*, and *u*, and each vowel must be printed in the same order as it appeared in .
2. Second, print each *consonant* (i.e., non-vowel) in  on a new line in the same order as it appeared in .

```javascript
const vowels=['a','e','i','o','u'];
function vowelsAndConsonants(s) {
    for (var letter of s){ //iterate letter (VALUES) in input string, CANNOT USE OF IN LOOP
    //using for in loop logs 01234 which are the KEYS of the strings with have values aeiou
        if(vowels.includes(letter)){ //filterpool.includes(iterateed letter)
        console.log(letter);
    }}
    for (var letter of s){
        if(!vowels.includes(letter)){
            console.log(letter);
        }
    }
}
function main() {
    const s = readLine();
    
    vowelsAndConsonants(s);
}
```

{% hint style="warning" %}
Difference between for-in and for-of loops: keys vs values example:

```javascript
let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}
```

{% endhint %}

### Factorial in JavaScript

```javascript
//Task: given 7, to find 7! = 7*6*5*4*3*2 and so on
function factorial(n){
    for (var i = n; i>=1; i--){
        n*=1;
    } return n
}
//SOLUTION 1 -RECURSION
function factorial(n){
    return (n*factorial(n-1))
}
```

## Day 3 : Arrays

{% hint style="success" %}

#### To sort array by numerical size, need add comparison function as shown in 1, befofe applying arrayname.sort to the function name :

1. function compareNumber(a,b){

&#x20;   return a - b; }

2\. array.sort(compareNumber)
{% endhint %}

Task : Given an array, return the second largest integer in the array

```javascript
function getSecondLargest(nums) {
    // initialize
    let firstLargestNum = 0;
    let secondLargestNum = 0;
    
    //first part: iterate length of array nums
    //update our counters as we iterate up the array
    for (let i =0; i < nums.length; i++){
        if(nums[i] > firstLargestNum ){
            secondLargestNum = firstLargestNum; // the order make sures secondLN takes on second biggest value before 1stLN updates to largest
            firstLargestNum = nums[i];
        }
        //second part covers the possibility of nums[i]<first but bigger than secondLN
        //first loop only activates when sums[i] bigger than firstLN
        if(nums[i]<firstLargestNum && nums[i]>secondLargestNum){
            secondLargestNum = nums[i];
        }
    }
    // console.log(firstLargestNum) logs 6, good
    return secondLargestNum
}
```

#### Day 3 : Try, Catch and Finally - Strings Manipulation

### Strings Basic Manipulation

* `String.charAt() -` Returns the character at the specified index
* `String.concat() -`Returns a new string consisting of the calling string concatenated with another string passed as an argument --> string1.concat(string2)
* `String.includes() -`Returns a boolean denoting whether a string passed as an argument exists within the calling string.
* `String.endsWith() -` Returns a boolean denoting whether the calling string ends with the characters of another string passed as an argument.
* `String.indexOf() -` Returns an integer denoting the index within the calling String object of the *first* occurrence of the given argument
* `String.lastIndexOf() -` Returns an integer denoting the index within the calling String object of the *last* occurrence of the given argument
* `String.match() -` Match a regular expression passed as an argument against the calling string. If a match is found, it returns an object with three properties: the matched substring, the `index` it was found at, and the `input` (i.e., the initial string)
* `String.normalize() -` Returns a string containing the Unicode Normalization Form of the calling string's value.
* `String.repeat() -` Returns a string consisting of the elements of the calling String object repeated some number of times (given as an integer argument). If no argument or a argument are given, then it returns the empty string.
* `String.replace() -` Finds a match between a regular expression and a string, then returns a string where the first matched substring is replaced with a new substring.

```javascript
var s = "HackerRank";
console.log(s.replace() + " " + s.replace("a", ""));     

//HackerRank HckerRank
```

* `String.search() -` Executes the search for a match between a regular expression and a specified string, then returns the index of the first character of the first match.
* `String.slice() - google this`
* `String.split()`
* `String.startsWith() -` Returns a boolean denoting whether a string begins with the characters of another string passed as an argument
* `String.substr() -` Returns a substring consisting of characters in a given range, depending on the arguments passed to the function
* String.toLowerCase() | String.toUpperCase() | String.trim() - trim whitespaces

### Try, Catch and Finally Code

<https://www.hackerrank.com/challenges/js10-try-catch-and-finally/topics>

The *try* block is the first step in error handling and is used for any block of code that is likely to raise an exception. It should contain one or more statements to be executed and is typically followed by at least one *catch clause* and/or the optional *finally clause*. In other words, the *try* statement has three forms:

* *try-catch*
* *try-finally*
* *try-catch-finally*

**The&#x20;*****catch*****&#x20;block immediately follows the&#x20;*****try*****&#x20;block and is executed only if an exception is thrown when executing the code within the&#x20;*****try*****&#x20;block.** It contains statements specifying how to proceed and recover from the thrown exception; if no exception is thrown when executing the *try* block, the *catch* block is skipped. If any statement within the *try* block (including a function call to code outside of the block) throws an exception, control immediately shifts to the catch clause.

The *finally* block is **optional**. It executes after the *try* and *catch* blocks, but before any subsequent statements following these blocks. **The&#x20;*****finally*****&#x20;block always executes, regardless of whether or not an exception was thrown or caug**ht.

```javascript
"use strict"

function getElement(arr, pos) {
    return arr[pos];
}


//let arr = [1, 2, 3, 4, 5];

try {
    console.log(getElement(arr, 4));
} 
catch (e) {
    console.log(e.message);
}
console.log("The program continued executing!");    

//output:
//arr is not defined
//The program continued executing!
```

### Task: Reverse String with Try, Catch, Finally

Complete the *reverseString* function; it has one parameter, . You must perform the following actions:

1. *Try* to reverse string  using the *split*, *reverse*, and *join* methods.
2. If an exception is thrown, *catch* it and print the contents of the exception's message on a new line.
3. Print s on a new line. If no exception was thrown, then this should be the reversed string; if an exception was thrown, this should be the original string.

```javascript
function reverseString(s) {
    try {
        s = s.split("").reverse().join("");
    } catch (e) {
        console.log(e.message);
    } finally {
        console.log(s);
    }
}
//Try - main function
//Catch - if try fails, catch activates to print error message    
//finally - activates regardless of try fail or pass   
```

## Day 3 : Throw and Catch

1. **The theory lesson**

**Errors** “indicates serious problems that a reasonable application should not try to catch.” This refers to problems that the application can not recover from - they should be dealt with by modifying application architecture or by refactoring code. **Exceptions,** on the other hand, indicate “conditions that a reasonable application might want to catch.” These could include problems that can occur at compile-time (checked exceptions) or run-time (unchecked exceptions) and can happen rather frequently in most applications

When we develop something, we often need our own error classes to reflect specific things that may go wrong in our tasks. For errors in network operations we may need `HttpError`, for database operations `DbError`, for searching operations `NotFoundError` and so on.

Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have a `statusCode` property with a value like `404` or `403` or `500`.

JavaScript allows to use `throw` with any argument, so technically our custom error classes don’t need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error` to identify error objects. So it’s better to inherit from it.

As the application grows, our own errors naturally form a hierarchy. For instance, `HttpTimeoutError` may inherit from `HttpError`, and so on.

<img src="https://2068334946-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fow1iM27u7disHeJiSlBC%2Fuploads%2Fc2DGDHaVLzOJHha67Jcv%2Fimage.png?alt=media&#x26;token=7fedacdf-c5e8-4fcc-b967-2427d91abf6f" alt="The errors hierarchy" data-size="original">

{% embed url="<https://www.hackerrank.com/challenges/js10-throw/topics>" %}
3 types of errors : Syntax, logical and Runtime (exceptions)
{% endembed %}

#### **2. Back to the question**&#x20;

**There are 2 ways to throw an error:**

* We can throw an exception by following the keyword `throw` with some  that we wish to use for the exception being thrown.
* We can throw an exception by following the keyword `throw` with `new Error(customError)`, where customError is the value we want for the message property of the exception being thrown ( **TLDR: USE new Error() for custom errors**)

```javascript
// 1. THROW - normal
function throwString() {
    // Generate an exception with a String value
    throw "some exception";
}
function throwFalse() {
    // Generate an exception with a boolean value of false
    throw false;
}
function throwNumber() {
    // Generate an exception with a Number value of -1
    throw -1;
}
try {
    throwString();
}
catch (e) {
    console.log(e);
}
try {
    throwFalse();
}
catch (e) {
    console.log(e);
}
try {
    throwNumber();
}
catch (e) {
    console.log(e);
}
// 2. THROW new Error() - Custom error
function getValue(arr, pos) { 
if (pos < 0) { 
throw new Error("Index Underflow: " + pos); 
}
let len = arr.length;if (pos >= len) { 
   throw new Error("Index Overflow: " + pos);
}return arr[pos];
}
```

3\. HackRank Question

Complete the *isPositive* function below. It has one integer parameter, a . If the value of a is positive, it must return the string `YES`. Otherwise, it must *throw* an *Error* according to the following rules:

* If  a ==0 , *throw* an *Error* with  `Zero Error`.
* If  a is negative, *throw* an *Error* with  `Negative Error`.

```javascript
function isPositive(a) {
    if ( a > 0 ) {
    return "YES"; 
   } else if ( a == 0 ){
   throw new Error("Zero Error"); // NOTE: these are custom errors hence need the 
   // Throw new Error()
   } else {
   throw new Error("Negative Error");
   } 
}
```

## Day 4 : Objects Basics

1. **Theory Lesson : Objects**

We define the following:

* *Object:* A collection of properties.
* *Property:* An association between a *name* (i.e., *key*) and a *value*. Note that when the value associated with a key is a function, we call the property a *method*. A property name can be any valid string, or anything that can be converted into a string (including the empty string).

An object has properties associated with it, and we explain an object's properties as variables that are part of the object. We can think of an object's properties as a set of regular variables specific to that object that define its characteristics.

Let's say we have an object named  and a property named . We can access this property in the following ways:

1. *Dot Notation:* Call `objectName.propertyName`.
2. *Bracket Notation:* Call `objectName['propertyName']`. Note that  must be enclosed in string quotes and is *case-sensitive*. Any property name that's not a valid JavaScript identifier (e.g., starts with a number, contains a space or hyphen, etc.) can only be accessed using bracket notation. This type of notation is also good to use when property names are dynamically determined (i.e., not known until runtime).

```javascript
// Create an object with two properties, 'Name' and 'Age'
var actor = {
    Name: 'Julia Roberts', 
    Age: 36
};
// Print the object
console.log('The \'actor\' object:', actor);

// Access object's properties using bracket notation
console.log('The \'Name\' property:', actor['Name']);

// Access object's properties using dot notation
console.log('The \'Age\' property:', actor.Age);

// Add a new property called 'EyeColor'
actor.EyeColor = 'Brown';

// Print the object
console.log('The updated \'actor\' object:', actor);

// Trying to access undefined property results in 'undefined'
console.log('Attempt to access an undefined property (\'HairColor\'):', 
    actor.HairColor);
```

2\. HackerRank Question

Modelling a rectangle by object creation, with properties of area, perimeter, width and length.

```javascript
//Input filter
'use strict';
process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();    
});
function readLine() {
    return inputString[currentLine++];
}
// Complete the Rectangle function *** MAIN *** 
function Rectangle(a, b) {
    this.length = a //this to refer to the object, properties after the dot
    this.width = b //this.property --> 
    this.perimeter = 2*(a+b)
    this.area = a*b
}
// Calling the function
function main() {
    const a = +(readLine());
    const b = +(readLine());
    const rec = new Rectangle(a, b);
    console.log(rec.length);
    console.log(rec.width);
    console.log(rec.perimeter);
    console.log(rec.area);
}
```

## Day 4 : Counting Objects

1. Theory Lesson (For in, For each)

The *for...in* statement iterates over the enumerable properties of an object in an arbitrary order, which allows us to execute statements for each distinct property. In the case of an array, the property would be its elements. In the case of an object, that would be its properties.

```javascript
// 1. FOR ITERATING OVER OBJECTS
const o = {
    a: 1,
    b: 2,
    c: 3,
    d: 4
};
console.log('property: value');
// 'p' is the property
for (p in o) {
    console.log(p + ': ' + o[p]);
} // output is in the format a: 1, b: 2 and so on.

// 2. FOR ITERATING OVER ARRAYS
const o = ['first', 'second', false];

// 'p' is the index
for (let p in o) {
    console.log(p + ' ' + o[p]);
}

// 3. FOR EACH
const arr = ['a', 'b', 'c', 'd'];

arr.forEach((value, index, array) => {
    console.log('index', index, 'has a value of', value,
    'which correlates to array[' + index + ']:', array[index]);
});

arr.forEach((value, index) => {
    console.log('index', index, 'has a value of', value);
});

arr.forEach((value) => {
    console.log('value:', value);
});
```

2\. HackerRank question - Iterating over Objects

Complete the function in the editor. It has one parameter: an array, a , of objects. Each object in the array has two integer properties denoted by x and y . The function must return a count of all such objects in array that satisfy o.x == o.y.

In my method I used the standard iteration of objects\[i].x or objects\[i].y.

```javascript
// Input format
5
1 1
2 3
3 3
3 4
4 5
//Output expected = 2

// Return a count of the total number of objects 'o' satisfying o.x == o.y.
// objects: an array of objects with integer properties 'x' and 'y'
 
function getCount(objects) {
    //initialise counter
    let counter = 0
    for (let i = 0; i < objects.length; i ++){
        if ( objects[i].x == objects[i].y ){
            counter += 1}}
    return counter
}
// Calling the Function
function main() {
    const n = +(readLine());
    let objects = [];
    
    for (let i = 0; i < n; i++) {
        const [a, b] = readLine().split(' ');
        objects.push({x: +(a), y: +(b)});
    }
    console.log(getCount(objects));
}
```

Alternative methods from the forums

```javascript
// 1. FILTER FUNCTION
// objects gets filtered.
// Only these objects get through the filter, that are true when comparing their x and their y value.
// The length of the filtered objects gets returned.
function getCount(objects) {
    return objects.filter(function(o){return o.x==o.y}).length
}
// 2. Using condition to true or false
function getCount(objects) {
    let n = 0;
    for(let o of objects) {
        n += (o.x == o.y); // the condition in parenthesis returns True or False
        // True or False in arithmetic translates to 1 and 0 respectively
    } //True will add 1 to counter n
    return n;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://davin-hong3.gitbook.io/d/programming/hackerrank/hackerrank-10-days-javascript-challenge.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
