Largest Number ( javascript ) explanation - javascript

I was working on leetcode question and come across this question and saw an answer online.
According the MDN, we should an inner function sort(function(a,b) return a + b) to sort an array properly.
Can someone explain how does the closure works and further explain the following codes?
(I don't quite understanding the sequence of how the comparison is done)
/*Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.
Note: The result may be very large, so you need to return a string instead of an integer.*/
var largestNumber = function(nums) {
return nums.sort(function (a,b){
return (b + '' + a) - (a + '' + b);
}).join('').replace(/^0*/,'') || '0';
};
var nums= [3, 30, 34, 5, 9]
console.log(largestNumber(nums));

What this sort is basically doing is for each element in the array a and b. Check which way the numbers would be high based on how they would be ordered. For example, if a = 30 and b = 5. Then:
(b + '' + a) - (a + '' + b)
530 - 305
225
Since this is a positive number it means b would be the left of of a in the final array (string).
So notice that in the example data [3, 30, 34, 5, 9], the element 9 compared to any other element would result in 9 being on the left (meaning it's the lowest item in the array). Here is a snippet example of each comparison done with some extra console information (to show how each comparison is being done and the result, notice that 9 was always lower compared to each element. Then the next number 5 is lower than everything but 9):
var largestNumber = function(nums) {
return nums.sort(function (a,b){
var priority = (b + '' + a) - (a + '' + b)
console.log((b + '' + a) + " - " + (a + '' + b) + " => " + (priority));
if(priority > 0) console.log(a + " > " + b);
else console.log(a + " < " + b);
return (b + '' + a) - (a + '' + b);
}).join('').replace(/^0*/,'') || '0';
};
var nums= [3, 30, 34, 5, 9]
console.log(largestNumber(nums));

The snipped you presented is basically a code that builds the largest possible "number" out of the elements of an array.
Lets imagine we have the following input: [3, 30, 34, 5, 9]
First of all, the sort is taking a function as parameter. Its job is to sort the nums in descending lexicographic order (so a 34 would be lesser than a 5, because 3 is lesser than 5). It does that by comparing the values of the strings composed by the "ab" and "ba", so if "ba" - "ab" is a negative value, it will assume that 'a' is lesser than 'b', and so on.
At this step you have: [9,5,34,3,30]
After the sorting takes place, it invokes the join() function with '' as parameter, which means it will join the elements into a string, separating each element with the given paramenter, which is no separation at all.
At this step you have: "9534330"
Then, you have a call to the replace function, which will look for a certain pattern and replace it by the given second parameter. The first parameter in this case is a regular expression, which will match each string with '0' at the beginning of it and that contain zero or more occurences of '0'.
(Reference to Regular expressions: http://www.w3schools.com/js/js_regexp.asp)
At this step you still have: "9534330"
Finally, at the end of the return expression there is an || '0', which basically means that it will return '0' in case the first part of the return expression is false, either by wrong or missing input.

Related

Writing a Javascript function to find the average of digits of a number by recursion

I am trying to find the average the sum of digits of a number.
For example, for the number 123, the sum of digits of 123 is 6 and the number of digits in 123 is 3.
So, the average of digits of 123 is 6/3 = 2.
I've only gotten as far as trying to find the sum through recursion unfortunately and often comes up as undefined. If I could figure this out I could find the average comfortably.
function averageOfDigits(number) {
// Make the whole number into a string first to get the individual digits
let arrOfStr = number.toString().split('');
// Convert this array into integers
let arrOfNum = arrOfStr.map(parseFloat)
// Find sum of these digits using recursion
let sum = function sumRecursion (arrOfNum) {
if (arrOfNum.length === 1) {
return arrOfNum[0]
} else {
return arrOfNum.pop() + sum(arrOfNum)
}
}
}
console.log(averageOfDigits(999))
You were close. Your implementation is setting sum equal to the recursive function, so that function is never getting called inside averageOfDigits. I think the confusing part was referring to the same function by two different names.
Here I define the sum function once, then call it twice. First is the internal recursive call, and second is in the return statement.
function averageOfDigits(number) {
// Make the whole number into a string first to get the individual digits
let arrOfStr = number.toString().split('');
// Convert this array into integers
let arrOfNum = arrOfStr.map(parseFloat)
// Find sum of these digits using recursion
function sum(arrOfNum) {
if (arrOfNum.length === 1) {
// base case reached
return arrOfNum[0];
} else {
// return first digit + recursive call
return arrOfNum.pop() + sum(arrOfNum);
}
}
return sum(arrOfNum);
}
console.log(averageOfDigits(999))
You can finish off the averageOfDigits function by replacing the return statement with your own code. Right now it just returns the sum.
It's missing the initial call to the recursive function.
Hint:
return (function sum(arr) {
if (arr.length === 1) {
return arr[0]
} else {
return arr.pop() + sum(arr)
}
}(arrOfNum))
There are several interesting alternative recursive approaches. Our first one treats the number as a string and proceeds from there:
const _avgOfDigits = ([d, ...ds], total, count) =>
d == undefined
? total / count
: _avgOfDigits (ds, total + Number (d), count + 1)
const avgOfDigits = (n) =>
_avgOfDigits (String (n) .split (''), 0, 0)
console .log (avgOfDigits (8675309)) //=> 5.428571428571429
Here we have a shell function that turns our number into an array of single-digit strings, then calls the private recursive function passing that array, and zeros for total and count. Our private function separates off the first digit and adds it to the total, increments the count, and recurs with these values and the remaining digits. When there are no more digits we return the quotient of the total and the digit count.
Our second one is more mathematical:
const avgOfDigits = (n, total = 0, count = 0) =>
n == 0
? total / count
: avgOfDigits (Math .floor (n / 10), total + n % 10, count + 1)
console .log (avgOfDigits (8675309)) //=> 5.428571428571429
Here we deal with the last digit and the remaining ones independently, turning, say, 8675309 into 9 and 867530, and using the 9 to increase our total, again incrementing our count, and recurring with 867530 and these new values. The recursion bottoms out the same way, and we return the same quotient.
A final sample is not recursive, showing an interesting running calculation for our average, not explicitly storing a total anywhere, and deriving the count from the running index:
const avgOfDigits = (n) => String (n) .split ('') .reduce (
(avg, digit, idx) => (avg * idx + Number (digit)) / (idx + 1),
0
)
console .log (avgOfDigits (8675309)) //=> 5.428571428571429
Here we keep a running average, which we adjust using the index as a count of digits seen so far. The efficiency will suffer because on each iteration, we are not just adding two numbers but also performing a multiplication and a division. And it offers little over other simpler versions, but a variant of it could be used successfully with some sort of scan function.
Update
I didn't explain what I meant by that scan comment. The idea is simple enough. scan is a function that acts like reduce but keeps all the partially accumulated values. So scan ((a, b) => a + b)) (0) ([1, 2, 3, 4, 5]) //=> [1, 3, 6, 10, 15], which is [(1), (1 + 2), (1 + 2 + 3), (1 + 2 + 3 + 4), (1 + 2 + 3 + 4 + 5)].
It's easy enough to write a scan function, and with one of those, this style of averaging may become more useful. For example,
const scan = (fn) => (init) => (xs) =>
xs .reduce ((a, x, i) => a .concat (fn (i == 0 ? init : a [i - 1], x, i)), [])
const digitAvgs = scan (
(avg, digit, idx) => (avg * idx + Number (digit)) / (idx + 1),
) (0)
console .log (digitAvgs ([8, 6, 7, 5, 3, 0, 9]))

What am I missing in my approach to this Dynamic Programming problem? (Leetcode 740. Delete and Earn)

I'm trying to understand how to solve Leetcode Problem #740: Delete and Earn
I recently was given this problem as part of a pre-interview assessment and was unable to complete it in the allotted time. I've been working on it today to try and wrap my head around it, but I'm kinda spinning in circles at the moment. I've checked numerous resources, videos, tutorials, etc, but I'm working in vanilla JS and a lot of the guides are in C++, Python, or Typescript which I don't currently know. (I plan on learning Python and Typescript at minimum, but I'm working with my current set of knowledge for the time being). This is leading to confusion and frustration, as an accurate translation of sample python/c++ code, etc continues to elude me.
The problem is as follows:
You are given an integer array nums. You want to maximize the number of points you get by performing the following operation any number of times:
Pick any nums[i] and delete it to earn nums[i] points. Afterwards, you must delete every element equal to nums[i] - 1 and every element equal to nums[i] + 1.
Return the maximum number of points you can earn by applying the above operation some number of times.
Example 1
Input: nums = [3,4,2]
Output: 6
Explanation: You can perform the following operations:
- Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2].
- Delete 2 to earn 2 points. nums = [].
You earn a total of 6 points.
Example 2
Input: nums = [2,2,3,3,3,4]
Output: 9
Explanation: You can perform the following operations:
- Delete a 3 to earn 3 points. All 2's and 4's are also deleted. nums = [3,3].
- Delete a 3 again to earn 3 points. nums = [3].
- Delete a 3 once more to earn 3 points. nums = [].
You earn a total of 9 points.
What I have so far:
const deleteAndEarn = (nums) => {
if(!nums || nums.length === 0) return 0;
if(nums.length === 1) return nums[0];
if(nums.length === 2) return nums[1];
const freq = makeDict(nums);
let prevNum
let [keep, avoid] = [0, 0];
for(const num of [...Object.keys(freq)].sort()){
let max = Math.max(keep, avoid)
if(parseInt(num) - 1 !== prevNum){
[keep, avoid] = [
(freq[num] * parseInt(num)) + max,
max
]
}else{
[keep, avoid] = [
parseInt(num) * freq[num] + avoid,
max
]
}
prevNum = parseInt(num)
}
return Math.max(keep, avoid)
};
const makeDict = (nums) => {
const dict = {}
for(const num of nums){
dict[num] = !!dict[num] ? dict[num]++ : 1
}
return dict
}
Provided Python Solution
This is what I've tried to model my code off of, but I don't actually know Python syntax so I'm sure I'm missing something.
class Solution(object):
def deleteAndEarn(self, nums):
count = collections.Counter(nums)
prev = None
avoid = using = 0
for k in sorted(count):
if k - 1 != prev:
avoid, using = max(avoid, using), k * count[k] + max(avoid, using)
else:
avoid, using = max(avoid, using), k * count[k] + avoid
prev = k
return max(avoid, using)
I really don't understand at all why this code isn't working, and I've even gone as far as to run sample cases step by step. Please help me understand how to do this so I can get a job!
Many thanks
I figured it out! The problem is twofold.
Bug Number One
First, shoutout to David Eisenstat for catching the bug in my makeDict() function.
The incorrect line of code reads:
dict[num] = !!dict[num] ? dict[num]++ : 1
Whereas the correct syntax is as follows:
dict[num] = !!dict[num] ? ++dict[num] : 1
or alternatively
dict[num] = !!dict[num] ? dict[num] + 1 : 1
The issue comes from how postfix vs prefix increment operators work in Javascript.
From the MDN docs:
If used postfix, with operator after operand (for example, x++), the increment operator increments and returns the value before incrementing.
If used prefix, with operator before operand (for example, ++x), the increment operator increments and returns the value after incrementing.
Bug Number Two
The second issue comes from my initial guard clauses.
if(nums.length === 2) return nums[1];
I think this was a remnant from when I was sorting the provided array at the very start, but even then automatically selecting the last element doesn't really make any sense. I deleted this line and, combined with the adjustment to the previous makeDict() function, the code passed all the provided tests.
My working solution is provided below. Open to any suggestions as to how to improve the code for both readability, or efficiency.
Appreciate the help!
const deleteAndEarn = (nums) => {
if(!nums || nums.length === 0) return 0;
if(nums.length === 1) return nums[0];
const freq = makeDict(nums);
let prevNum
let [keep, avoid] = [0, 0];
for(const num of Object.keys(freq)){
let max = Math.max(keep, avoid)
if(parseInt(num) - 1 !== prevNum){
[keep, avoid] = [
(freq[num] * parseInt(num)) + max,
max
]
}else{
[keep, avoid] = [
parseInt(num) * freq[num] + avoid,
max
]
}
prevNum = parseInt(num)
}
return Math.max(keep, avoid)
};
const makeDict = (nums) => {
const dict = {}
for(const num of nums){
dict[num] = !!dict[num] ? ++dict[num] : 1
}
return dict
}
One bug in your existing code is that
[...Object.keys(freq)].sort()
will not sort numbers in order - see here.
Another bug is that your algorithm doesn't have any backtracking - you don't want to greedily choose 3 when given [3, 4, 4, 4].
I think the best way to approach this is to understand that it's only strings of consecutive numbers in the input that need to be considered. For example, given
[1, 2, 3, 6, 7, 8]
Separate it out into all the consecutive strings of integers:
[1, 2, 3]
[6, 7, 8]
Then decide the optimal picks for each sequence.
You can't just pick all odd numbers or all even numbers in the sequence, because that would fail to pick, eg, 1 and 4 for [1, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4]. The best approach I can see is to use a recursive function: when checking a sequence, getBestSequenceSum, starting with N, return the maximum of:
Sum of N plus getBestSequenceSum(seq.slice(2)) (skipping the next item in the sequence), OR
Sum of getBestSequenceSum(seq.slice(1)) (using the next item in the sequence)
to adequately cover all possibilities.
There may be more efficient algorithms, but this is relatively simple and intuitive.
const getBestSequenceSum = (seq) => {
if (seq.length === 0) return 0;
// Include the lowest value in the sequence, or not?
const sumOfLowestVal = seq[0].num * seq[0].count;
return Math.max(
sumOfLowestVal + getBestSequenceSum(seq.slice(2)),
getBestSequenceSum(seq.slice(1))
);
};
const deleteAndEarn = (nums) => {
nums.sort((a, b) => a - b);
let lastNum;
const sequences = [];
for (const num of nums) {
if (num !== lastNum && num !== lastNum + 1) {
// New sequence
sequences.push([]);
}
const thisSequence = sequences[sequences.length - 1];
if (num !== lastNum) {
thisSequence.push({ num, count: 0 });
}
thisSequence[thisSequence.length - 1].count++;
lastNum = num;
}
return sequences.reduce((a, seq) => a + getBestSequenceSum(seq), 0);
};
console.log(deleteAndEarn([10,8,4,2,1,3,4,8,2,9,10,4,8,5,9,1,5,1,6,8,1,1,6,7,8,9,1,7,6,8,4,5,4,1,5,9,8,6,10,6,4,3,8,4,10,8,8,10,6,4,4,4,9,6,9,10,7,1,5,3,4,4,8,1,1,2,1,4,1,1,4,9,4,7,1,5,1,10,3,5,10,3,10,2,1,10,4,1,1,4,1,2,10,9,7,10,1,2,7,5]));
The number of calculations could be reduced somewhat by changing the { num, count: 0 } objects to a single number instead, but that would be more difficult to understand when reading the code.
You could also reduce the number of calculations by caching already-optimized sequences so as not to recalculate them multiple times, but that'd make the code significantly longer.

Cycling through two arrays and matching elements in Javascript

I'm having trouble wrapping my head around an array matching problem in JavaScript.
I have two arrays:
array1 = ["a", "b", "c", "d", "e"];
array2 = ["t", "u", "v", "w", "x"];
What I want to achieve is a cycle that works through each array and returns an array of objects that represent matched groups following the pattern:
1 to 1
1 to 1,2
1,2 to 1
1,2 to 1,2
1,2,3 to 1
1,2,3 to 1,2
1,2,3,4 to 1
1,2,3,4 to 1,2
Then once the cycle is over step up to the second character and carry on through. So for the above two arrays the result would be:
result = [
{1_1: "a;t", 1_12: "a;tu", 12_1: "ab;t", 12_12: "ab;tu", 123_1: "abc;t", 123_12: "abc;tu", 1234_1: "abcd;t", 1234_12: "abcd;tu"},
{1_1: "b;u", 1_12: "b;uv", 12_1: "bc;u", 12_12: "bc;uv", 123_1: "bcd;u", 123_12: "bcd;uv", 1234_1: "bcde;u", 1234_12: "bcde;uv"},
...and so on
];
The arrays don't have a major limit, but they will most likely be in the 5 to 12 characters long region although the outer limits in length are as short as 1 and as long as 30. If the array is is shorter than 4 then it stops when it gets to the end of the process it can. So for example:
array1 = ["a"];
array2 = ["b"];
result = [{1_1: "a;b"}];
I am assuming there is a fun game of recursion buried in this, but I don't even know how to approach this problem let alone word it in a way to make my google searches effective. Any help you could offer regarding getting started would be very appreciated.
Edit in response to comment:
What I'm looking for specifically is terms I can search to help me get started or pseudo code that would help me start the process of tackling this problem. Thanks.
Alas Permutations came too late for me. Although it looks like I kind of went in that direction. I struggled with this until I gave up and just decided to essentially brute force an answer and this is what I came up with.
I am absolutely certain that this can be drastically simplified, but on this day I didn't have the mental capacity to get there. Sometimes you just have to force it. This is what I came up with:
const matchArrays = (array1: string[], array2: string[]): string[] => {
let a1List: string[] = [];
let resultList: string[] = [];
let count: number = 4;
(array1.length < 4) && (count = array1.length);
for (let i = 0; i < array1.length; i++) {
a1List.push(array1[i]);
array1[i + 1] !== undefined && a1List.push(array1[i] + array1[i + 1]);
array1[i + 2] !== undefined && a1List.push(array1[i] + array1[i + 1] + array1[i + 2]);
array1[i + 3] !== undefined && a1List.push(array1[i] + array1[i + 1] + array1[i + 2] + array1[i + 3]);
}
for (let i = 0; i < a1List.length; i++) {
resultList.push(a1List[i] + ";" + array2[Math.floor(i / count)]);
resultList.push(a1List[i] + ";" + array2[Math.floor(i / count)] + array2[Math.floor(i / count) + 1]);
}
return resultList;
};
Thanks to anyone who stopped to read this.

Array Addition I JavaScript function on Coderbyte

I am doing a challenge on Coderbyte and I would be grateful for any advice on my question:
The challenge given to me:
"Using the JavaScript language, have the function ArrayAdditionI(arr)
take the array of numbers stored in arr and return the string true if
any combination of numbers in the array can be added up to equal the
largest number in the array, otherwise return the string false.
For example: if arr contains [4, 6, 23, 10, 1, 3] the output should
return true because 4 + 6 + 10 + 3 = 23. The array will not be empty,
will not contain all the same elements, and may contain negative numbers. "
The way I attempted to solve it: http://jsfiddle.net/reLsg0fg/
function ArrayAdditionI(arr){
var newArr=arr.sort(); // sorted from smallest to largest.
var largestNum=newArr.slice(-1); // Gets the last number, which would be the largest.
var loopArr=arr.sort().pop(); // Takes out the largest number for adding later.
var result=0;
for(var i=0; i<loopArr.length; i++){ // loops through all numbers.
if(result/largestNum !== 1){ //when you divide a number by itself it will be 1.
result+=loopArr[i]; // keep adding each number until get largest number.
}else if(result === largestNum){
return true;
}
}
return false;
}
// TESTS
console.log("-----");
console.log(ArrayAdditionI([4,6,23,10,1,3]));
console.log(ArrayAdditionI([5,7,16,1,2]));
console.log(ArrayAdditionI([3,5,-1,8,12]));
I'm supposed to get true, false, true. But I get false, false, false as if something is wrong within my loop. JSFiddle: http://jsfiddle.net/reLsg0fg/
I would appreciate any suggestions. Thank you ^^
Sort Array using
arr.sort(function (a, b) { return a - b })
I have tried to solve this problem with a for loop but I missed the fact that the challenge
is not asking that all numbers need to add up to equal the largest num, but it is also possible to
add up to the largest num if we take some numbers out. Thus I decided to solve with recursion.
Tips:
* The Math.max.apply() method takes an array and returns the largest number. Note that it usually works on strings as Math.max().
* the sort() method can take a parameter to further expand it's purpose. Usually it only
sorts strings, but to sort numbers we include a function that finds which number is bigger.
* First get the largest number.
* Sort the array and remove the largest number to be used for recursion later.
* Create a recursion function that checks if the numbers add up to the largest number, and if not, check that if some numbers in array are subtracted from the largest num they are equal to the largest number.
function ArrayAdditionI(array){
var largestNum = Math.max.apply(0, array); // gets the largest number in array.
array.sort(function(a,b){ return a-b;}).pop(); // sorts array and removes last(largest) number.
function recursionCheck(arr, sum){
// the base case when array empty.
if(arr.length === 0){
return sum === 0;
}
var arrBeginNum=arr[0];
// for every recursion take away one number(the first one in this case).
arr = arr.slice(1);
// first check if numbers sum up to largest num if not, check if removing numbers adds up to largest num.
return recursionCheck(arr, sum) || recursionCheck(arr, sum - arrBeginNum);
}
// recursion needs to be called for it to start.
return recursionCheck(array, largestNum);
}
// TESTS
console.log("-----");
console.log(ArrayAdditionI([1,2,3,5,4])); ==> true
console.log(ArrayAdditionI([21,10,12,9,2])); ==> true
console.log(ArrayAdditionI([4,6,23,10,1,3])); ===> true
console.log(ArrayAdditionI([5,7,16,1,2])); ===> false
console.log(ArrayAdditionI([3,5,-1,8,12])); ===> true
This might not be the complete solution yet, but here are the JavaScript-Problems:
largestNum was an array in you algorithm
.sort() was not working
function ArrayAdditionI(arr){
var largestNum = Math.max.apply(0, arr); // Gets the last number, which would be the largest.
arr.sort(function(a, b){return a-b})
arr.pop(); // Takes out the largest number for adding later.
var result=0;
Also use if(result !== largestNum) {, Division is expensive and might have unexpected results with floating-point numbers.
Thats it for your JavaScript. But I am pretty sure the Algorithm is wrong - but I think this is up to you
Note that the example [4, 6, 23, 10, 1, 3] => 4 + 6 + 10 + 3 = 23 is not just adding up the lowest to the biggest value to try and match it.
A possible example of a solution for the problem.
How this works:
First sort all items descending
Shift the first element to largest
Call the recursive function y with the reduced array, the largest value and a variable which holds an empty array for the successfully added items.
The recursive function works basically in two parts
Test if the remaining sum is zero, if so the result is achieved and return true, which finished the function.
If not iterate through the array and
Make a copy from the array
Get the value from the position with splice
Test, if the value is smaller or equal the remaining sum and the result of the call of y with the shorted array, sum minus value and a new array with the used items and the acual item.
If true return true and finish the function.
If not finished before return false.
function x(array) {
function y(a, s, result) {
var aa, i, v;
if (s === 0) {
document.write('<pre>result: ' + JSON.stringify(result, 0, 4) + '</pre>');
return true;
}
for (i = 0; i < a.length; i++) {
aa = a.slice();
v = aa.splice(i, 1)[0];
if (v <= s && y(aa, s - v, result.concat(v))) {
return true;
}
}
return false;
}
var largest,
r = [];
array.sort(function (a, b) { return b - a; });
largest = array.shift();
document.write('largest value: ' + largest + '<br>');
return y(array, largest, r);
}
document.write(x([4, 6, 23, 10, 1, 3]) + '<hr>');
document.write(x([5, 7, 16, 1, 2]) + '<hr>');
document.write(x([3, 5, -1, 8, 12]));
Thanks #mar
Here is a version in Kotlin if someone needs
private fun returnResult(arr: Array<Int>): Boolean {
arr.sort()
val largestNumber = arr.last()
val arrWithoutLargest = arr.dropLast(1).toTypedArray()
return recursionCheck(arrWithoutLargest, largestNumber)
}
private fun recursionCheck(arr: Array<Int>, sum:Int): Boolean {
if (arr.isEmpty()) return sum == 0
val arrBeginNum = arr[0]
val arr2 = arr.drop(1).toTypedArray()
return recursionCheck(arr2, sum) || recursionCheck(arr2, sum - arrBeginNum)
}

Greater than returns wrong value on numbers lower then 100

This is my first JavaScript project, so I'm sure this code isn't pretty, and could be written in a much better way, but that aside, I've encountered a problem I just don't understand. I'm sure it's just a bug I've made myself, but I just simply can't find it.
The '>' (greater than) operator works fine on numbers over 100, but stops working when it gets to 100. For some reason 100 > 99 returns false?
https://jsbin.com/vigocu/edit?console,output
Move the slider to the right, and then slowly to the left, and you will see it returning "true" until it reaches 100. From there it returns "false"
function getSliderInput(inputSliderId) {
var backSwingArray = [100];
var downSwingArray = [];
document.querySelector('#' + inputSliderId).addEventListener('input', fillArray , false);
function fillArray() {
if (isNaN(downSwingArray[downSwingArray.length - 1]) && backSwingArray[backSwingArray.length - 1] < this.value) {
backSwingArray.push(this.value);
} else if (downSwingArray[downSwingArray.length - 1] > this.value || isNaN(downSwingArray[downSwingArray.length - 1])){
console.log('Is ' + downSwingArray[downSwingArray.length - 1] + ' > ' + this.value + ' return ' + (downSwingArray[downSwingArray.length - 1] > this.value));
downSwingArray.push(this.value);
} else {
console.log('Is ' + downSwingArray[downSwingArray.length - 1] + ' > ' + this.value + ' return ' + (downSwingArray[downSwingArray.length - 1] > this.value));
return;
}
}
}
value on input elements is always a string. While that won't be a problem initially, when you're comparing this.value to the 100 you've put in the array to start with, you then push this.value into the array as-is (as a string). That means later, you'll end up comparing that stored string with another this.value value, which is also a string. If either operand to > is a number, it will coerce the other operand to number (the way + does, see below), but if both operands are strings, it will do a lexical comparison, not a numeric one, and "100" is indeed < "99" because "1" is < "9".
So you want to convert this.value to a number early on, and then use that number both when comparing and when pushing into your array. You have many ways to do that:
The unary + will require the entire string to be a valid number, but will treat "" as 0; it will also treat strings starting with 0x as hexadecimal
var num = +this.value;
// or perhaps
var num = this.value === "" ? NaN : +this.value;
// or even
var str = this.value.trim(); // .trim can be shimmed on obsolete browsers
var num = str === "" ? NaN : +str;
parseInt(..., 10) (the 10 is specifying the radix [number base] to use) will allow garbage at the end of the string, treat "" as NaN, and treat any string prefixed with 0x as 0 (since it stops at the first invalid character)
var num = parseInt(this.value, 10);
Number(...) does what + does
var num = Number(this.value); // or variations above on +

Categories