In my last post i talked about, how i went from looking for a job using the ApplyByAPI to an interview question.
I split this in two part, so you can watch it in another tab, and switch it easily, instead of wheeling up and down with the mouse.
This is just for educational purposes.
Answer 1
The error take place when the condition evaluate the "Superman is awesome!"
and the indexOf
method return 0 (which is the index) and it's evaluate as false, so to prevent this, we could wrap the expression and compare to less than 0. (-1 means it could not found it).
function validateString(str) {
if ((str.toUpperCase().indexOf('superman'.toUpperCase())) < 0) {
throw new Error('String does not contain superman');
}
}
Answer 2
If you need to search elements in a sorted array, binary search algorithm is the way to go, their Big O is O(log n), so the steps to do it is:
- Define
let start = 0
andlet end = n-1
(where n-1 is the last element of the sorted array) - If
start
<end
, then stop: target is not present in array. Return -1. - 2. Compute
guess
as the average ofstart
andend
, rounded down (so that get an integer). - If
array[guess]
equalstarget
, then stop. You found it! Returnguess
. - If the
guess
was too low, that is,array[guess] < target
, then setstart = guess + 1
. - Otherwise, the
guess
was too high. Setend = guess - 1
. - Go to step 2
function binarySearch(sortedArray, key){
let start = 0;
let end = sortedArray.length - 1;
while (start <= end) {
let guess = Math.floor((start + end) / 2);
if (sortedArray[middle] === key) {
return guess;
} else if (sortedArray[middle] < key) {
start = guess + 1;
} else {
end = guess - 1;
}
}
return -1;
}
Answer 3
const phonenumberFormatter = (numberString, delimiter = '-') => {
let arrayInputPhoneNumberString = numberString.trim().split('')
let arrayOutputPhoneNumberString = []
const lengthUSPhoneBlock = 10 // 3-3-4 US block standard
let counterLenPhoneBlock = 0
arrayInputPhoneNumberString.forEach( (value) => {
if (parseInt(value) === 0 || parseInt(value)) {
counterLenPhoneBlock++
arrayOutputPhoneNumberString.push(value)
if (counterLenPhoneBlock === 3 || counterLenPhoneBlock === 6 ) {
arrayOutputPhoneNumberString.push(delimiter)
}
}
})
if(counterLenPhoneBlock === lengthUSPhoneBlock) {
return arrayOutputPhoneNumberString.join('').toString()
}
return 'missing numbers, check your phonenumber again'
}
Answer 4
// Assuming we set up our enviroment to use Import ES6 Syntax
import fizzBuzz from './fizzbuzz';
describe('Fizzbuzz Test', () => {
test('output 1 for input 1', () => {
expect(fizzBuzz).toEqual(1)
});
test('output "Fizz" for input 3', () => {
expect(fizzBuzz).toEqual('Fizz')
});
test('output "Buzz" for input 5', () => {
expect(fizzBuzz).toEqual('Buzz')
});
test('output 7 for input 7', () => {
expect(fizzBuzz).toEqual(7)
});
test('output "Fizz" for input 9', () => {
expect(fizzBuzz).toEqual('Fizz')
});
test('output "Buzz" for input 10', () => {
expect(fizzBuzz).toEqual('Buzz')
});
test('output "FizzBuzz" for input 15', () => {
expect(fizzBuzz).toEqual('FizzBuzz')
});
test('output "FizzBuzz" for input 45', () => {
expect(fizzBuzz).toEqual('FizzBuzz')
});
})
Answer 5
const hash = (name) => {
let hash = 0;
for (var i = 0; i < name.length; i++) {
/*
* retrieve the UTF-16 value
* while shift left the hash value
* (an hex value can be represent up to (2^5 -1) from 0 - 15 )
* minus the previous hash value ( for more random purpose )
*/
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
return hash;
}
const getColorFromName = (name) => {
let hashCode = hash(name)
let value = 0
let color = "#"
/*
* Build the hex char, i.e. #000000
*/
for (let i = 0; i < 3; i++) {
/*
* Nudge right 8 position from the hash up to 3 times
* and bring the commons bits from the hexadecimal higgest value.
* Then, build the color string.
*/
value = (hashCode >> (i * 8)) & 0xFF;
color += ('00' + value.toString(16)).substr(-2);
}
return color
}
To make code much modular and easy to maintain, we can pass to getColorFromName()
the hash
function as a second parameter.
Answer 6
In our IIFE, we need to access to addEventListener
from the getElementById
, so when listen the 'click' event,
we can trigger our code.
(function(){
for (var i = 0, l = 10; i < l; i++) {
document.getElementById('button-' + i).addEventListener('click', function (event) {
console.log('Line %s', i);
})
}
})();
However there is a couple gotchas here, hoisting and closure. You see, hosting is a very annyoning concept in the ES5
and below, is the process of initialize all functions and variables and place them into memory.
Functions are hosted in memory, but variable are initializes as undefined
, this is a behaviour we can avoid using
let
& const
thanks to the block scope, but this is for ES6, and we need to solve this on ES5.
So, we can use closure, and they allow functions to gain access variables to outer scope from inner scope. The Javascript Engine will keep those variables around inside function if they have reference to them, instead of "sweeping" them away after they popped off the call stack. Here is how we can solve this.
(function(){
for (var i = 0, l = 10; i < l; i++) {
(function(i){
document.getElementById('button-' + i).addEventListener('click', function (event) {
console.log('Line %s', i);
})
})(i)
}
})();
Here is the code sample with the html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="button-0">click 0</button>
<button id="button-1">click 1</button>
<button id="button-2">click 2</button>
<button id="button-3">click 3</button>
<button id="button-4">click 4</button>
<button id="button-5">click 5</button>
<button id="button-6">click 6</button>
<button id="button-7">click 7</button>
<button id="button-8">click 8</button>
<button id="button-9">click 9</button>
</body>
<script>
(function(){
for (var i = 0, l = 10; i < l; i++) {
(function(i){
document.getElementById('button-' + i).addEventListener('click', function (event) {
console.log('Line %s', i);
})
})(i)
}
})();
</script>
</html>
Answer 7
An iterable is a generalization of arrays, and technically having a method Symbol.iterator
makes one.
function isIterable(obj) {
// checks for null and undefined
if (obj == null) {
return false;
}
return typeof obj[Symbol.iterator] === 'function';
}
Top comments (1)
Here is a correction to Answer 2:
And even easier solution using the built-in "includes" method for arrays: