Exclude 0 from !value - javascript

I am trying to create a variant of the following code, but would like when stdin == 0 to continue with the prompts and break only on every other !value case.
So far I have managed to make it work when stdin is a string (no unary +) and with Number(value) converting at the end.
The problem with my checks is that both zero and !value convert to false, which is the standard case afaik. I have tried with AND, OR operators but with no luck.
let sum = 0;
while(true) {
let value = +prompt('Choose value:','');
if ( !value ) break;
sum += value;
}

value is a number, and the only falsy numbers are 0 and NaN. You can check for NaN directly:
if (isNaN(value)) break;
Keep in mind that +'' is 0 and not NaN, however. It might be more appropriate to save the cast for later. There’s even the option of applying stricter validation, ruling out inputs like Infinity or 1.2e3:
let sum = 0;
while (true) {
const input = prompt('Choose value:');
const value = Number(input);
if (isNaN(value) || input === null || input.trim() === '') {
break;
}
sum += value;
}

You can check directly if the value equals to zero:
let sum = 0;
while(true) {
let value = +prompt('Choose value:','');
if ( value !== 0 && !value ) break;
sum += value;
}
console.log(sum);

You could use a default value of NaN for getting an empty string '' before converting to number.
Then check if the value is not a number and break the loop.
let sum = 0;
while(true) {
let value = +(prompt('Choose value:').trim() || NaN);
if (isNaN(value)) break;
sum += value;
}
console.log(sum);

Related

Codwars: Array to single value +1

Given an array of integers of any length, return an array that has 1 added to the value represented by the array.
the array can't be empty
only non-negative, single digit integers are allowed
Return nil (or your language's equivalent) for invalid inputs.
Examples
For example the array [2, 3, 9] equals 239, adding one would return the array [2, 4, 0].
My code so far:
function upArray(arr){
let i = parseInt(arr.join('')) + 1;
return arr.some(e => typeof e !== 'number' || e < 0) ?
null : i
.toString()
.split('')
.map(e => parseInt(e));
};
It seems to pass most basic test however fails with larger inputs. Where have I gone wrong?
Just like you have converted the array into a number, you have to convert the number back into an array.
function upArray(arr){
let i = parseInt(arr.join('')) + 1;
return i.toString().split('').map(x => parseInt(x));
};
console.log(upArray([2,3,9]));
Your code won't work if the array length is greater than 100k...
Number type of javascript or any language is not enough big to handle it.
It's better if we calculate the last element with 1. If result is larger than nice ( < 10 ),
we continue to calculate next element with 1 and assign current value to 0. If result is smaller or equal 9, just assign the result to current and exit loop.
Then we print the final array as result:
pseudo code:
for i from: n-1:0
result = arr[i] + 1;
if(result < 10) :
arr[i] = result;
exit loop;// no need to continue calculate
else:
arr[i] = 0;
endif;
endfor;
You can join final array as string.
Here's probably the fastest solution (performance wise) - also there's no need to deal with BigInt, NaN, or Infinity:
function upArray(arr) {
if (!isInputIsNonEmptyArray(arr)) {
return null;
}
const isNumber = num => typeof num === 'number';
const isIntSingleDigit = num => Number.isInteger(num) && num >= 0 && num <10;
let resultArr = [];
let i = arr.length;
let num;
while (i-- > 0) {
num = arr[i];
if (!isNumber(num) || !isIntSingleDigit(num)) {
return null;
}
if (num === 9) {
resultArr[i] = 0;
if (i === 0) { //means we're in the msb/left most digit, so we need to insert 1 to the left
resultArr.unshift(1);
break; //you can leave it out really, as the next check in the while will fail anyway
}
}
else {
resultArr[i] = num + 1; //No more + 1 should be made, just check for validity
//of the rest of the input and copy to the result arr
while (--i > -1) {
num = arr[i];
if (!isNumber(num) || !isIntSingleDigit(num)) {
return null;
}
resultArr[i] = arr[i];
}
break;
}
}
return resultArr;
function isInputIsNonEmptyArray(arr) {
return Array.isArray(arr) && arr.length > 0;
}
}
If the input arg is not an array or an empty array, or if you encounter invalid element during the main while loop you return null.
In the main while loop you go from the right most element (lsd), and add 1 to it (or insert 0 if the number is 9) up the the left most digit.
If a number which is less than 9 is incremented, no need to increment any more (this is the while loop in the else clause).

console.log(-1) still returns NaN

I have my js code for homework here. I have an if statement that should return -1 in console when the input is not a number but instead of returning -1 it returns NaN. Can anybody help me with this?
function calculateFoodOrder(numAnimals, avgFood) {
// IMPLEMENT THIS FUNCTION!
var total = avgFood*numAnimals;
if ((Number(numAnimals || avgFood) < 0) && (isNaN(numAnimals || avgFood))) {
console.log(-1);
} else {
return total
}
}
calculateFoodOrder()
Default values in your function are 'undefined'. That's why javascript is showing NaN. Define default values to avoid this. For example:
function calculateFoodOrder(numAnimals = 0, avgFood = 0) {
var total = avgFood*numAnimals;
if ((Number(numAnimals || avgFood) < 0) && (isNaN(numAnimals || avgFood))) {
console.log(-1);
} else {
return total;
}
}
If I understand your task correctly, you merely have to check both parameters for not being NaN using isNaN.
Your sample code does not work because any comparison with NaN returns false and thus Number(numAnimals || avgFood) < 0 is never going to be true. Check here for details on NaN.
function calculateFoodOrder(numAnimals, avgFood){
//REM: Default result
let tResult = -1;
//REM: Check if both paramters are not NaN
//REM: Be aware that whitespaces and empty strings validate to zero
if(
!isNaN(numAnimals) &&
!isNaN(avgFood)
){
tResult = Number(avgFood) * Number(numAnimals)
};
return tResult
};
//REM: Default test case
console.log(calculateFoodOrder());
;document.querySelector('button').onclick = function(){
console.log(
calculateFoodOrder(
document.getElementById('innumAnimals').value,
document.getElementById('inavgFood').value
)
)
};
<input type = 'text' value = '' id = 'innumAnimals' placeholder = 'numAnimals' />
<input type = 'text' value = '' id = 'inavgFood' placeholder = 'avgFood' />
<button>do</button>
Please do not confuse yourself with caveats if you are a beginner. You should assign to itself after converting to number, then judge if it's a NaN value or less then zero just like this,
function calculateFoodOrder(numAnimals, avgFood) {
// IMPLEMENT THIS FUNCTION!
numAnimals = Number(numAnimals);
avgFood = Number(avgFood);
var total = avgFood * numAnimals;
if (isNaN(numAnimals) || isNaN(avgFood) || numAnimals < 0 || avgFood < 0 ) {
console.log(-1);
} else {
return total
}
}
calculateFoodOrder()

Summing a number's digits

My code below. Can someone see the mistake I made?
Write a function named sumDigits which takes a number as input and returns the sum of the absolute value of each of the number's decimal digits. For example:
sumDigits(10); // Returns 1
sumDigits(99); // Returns 18
sumDigits(-32); // Returns 5
Let's assume that all numbers in the input will be integer values.
function sumDigits(number) {
let numberstring = number.toString()
let numberarr = numberstring.split("")
let counter = 0
for(var i=0; i<numberarr.length; i++) {
if(typeof numberarr[i] === "number") {
console.log(numberarr[i])
let numbervalue = Number(numberarr[i])
console.log(numbervalue)
counter += numbervalue
} else if (typeof numberarr[i] !== "number"){
counter += 0
}
}
return counter
}
console.log(Math.abs(sumDigits(10))); // Returns 1
console.log(Math.abs(sumDigits(99))); // Returns 1
console.log(Math.abs(sumDigits(-32))); // Returns 1 // Returns 5
//Let's assume that all numbers in the input will be integer values.
function sumDigits(number) {
var counter = 0;
var remainder;
number=Math.abs(number);
while(number>0){
counter=counter+number%10;
number=Math.floor(number/10);
}
return counter;
}
I think you are looking for some code like this. i don't get why you convert your number to string.
number=Math.abs(number); this line first convert any negative number to positive.
sumDigits(number) takes an argument as now loop through the number until number < 0 then add the remainder to counter variable then return counter as final sum
Try this solution:
console.log(sumDigits(-103)); // Returns 4
function sumDigits(number) {
var numberstring = number.toString();
var counter=0;
for(var i=0; i<numberstring.length; i++){
if(parseInt(numberstring.charAt(i))){
counter += parseInt(numberstring.charAt(i));
}
}
return counter;
}
This
if(typeof numberarr[i] === "number")
statement is always false, because before you convert the number into a string. I think that your function return always zero.
The answer by giovybus & Raman are correct, if you were wondering why your snippet didn't work - it's because the reference of the numberer[I] will always be a string. numberarr is a string array, not a number array, you needed to convert it to a number before using. Adjustments to your code above as below
sumDigits(10); // Returns 1
sumDigits(99); // Returns 18
sumDigits(-32);
function sumDigits(number) {
let numberstring = number.toString().replace("-", "");
let numberarr = numberstring.split("")
let counter = 0
for(var i=0; i<numberarr.length; i++) {
const numbervalue = Number(numberarr[i])
if(typeof numbervalue === "number") {
counter += numbervalue
} else if (typeof numbervalue !== "number"){
counter += 0
}
}
console.log(counter)
return counter
}
However this is not a good solution and you should consider using solution by giovybus, Raman or anyone else with better approach instead.
Using filter and reduce to calculate the total.
function sumDigits(number) {
return ( [...number.toString()]
.filter( (char) => !isNaN(parseInt( char ) ) )
.reduce( function(a,b) { return a + parseInt(b) }, 0) );
}
const sum1 = sumDigits(103);
console.log( sum1 );
const sum2 = sumDigits(-105);
console.log( sum2 );
Using latest ES6 syntax...
function sumDigits(num) {
return [...num.toString()].map(Number).reduce((acc, val) => acc + val, 0);
};
console.log(sumDigits(55)); // 10
Explanation of tricky parts:
This will split the string into an array of digits:
[..."1234"] // => [ "1", "2", "3", "4" ]
This will transform it into Numbers
[ "1", "2" ].map(Number) // => [ 1, 2 ]

Script validation a number 1-100

So I need to write a script that validates a number that is great than zero and less than 100. The catch is that the number can only be accepted if there is decimal in the middle position and has at least two decimal places.
Examples: 19.30 would validate but 9.3, 9.30, and 19.3 would be considered invalid.
I'm thinking a regular expressions would be the best way to validate the decimal criteria?
Comments in the code:
function validNumber(string) {
// parse string into number
let number = parseFloat(string, 10);
// check if number is in range
if (number <= 0 || number >= 100) return false;
// check if number is formatted correctly
if (string !== number.toFixed(2)) return false;
// return true if all conditions pass
return true;
}
console.log(validNumber("19.30")); // true
console.log(validNumber("9.3")); // false
console.log(validNumber("19.3")); // false
console.log(validNumber("100.30")); // false
console.log(validNumber("1.00")); // true
What you could do is split on the decimal, then the test the lengths of the strings.
function validate(number) {
let [whole, decimal] = number.toString().split('.', 2)
let int = parseInt(whole)
return whole.length == decimal.length && decimal.length >= 2
&& int > 0 && int < 100
}
console.log(validate('19.30'))
console.log(validate('9.3'))
console.log(validate('9.30'))
console.log(validate('-9.30'))
console.log(validate('19.3'))
console.log(validate('99.99'))
console.log(validate('1.111'))
console.log(validate('100.111'))
console.log(validate('1000.111'))
The following regex meets your needs I think provided input is string along with comparison operator
\d{1,3}\.\d{2}+
You could use it as following:
const isValid = (input) => {
const num = parseFloat(input, 10);
return (!!input.match(/\d{1,3}\.\d{2}+/) && num > 0 && num < 100);
};
isValid('19.3') // => false
isValid('19.30') // => true

How to clear text field using javascript with a condition?

I want if I clear the text field #t1, text field #d1 should clear. But last two lines dont do it....
function utl()
{
var a = document.getElementById('t1');
var z = document.getElementById('d1');
if (a!=0)
{
var y = parseFloat(a.value) * 100;
y = y || 0;
z.value = y.toFixed(2);
}
else if (a==0)
z.value = 0;
else if (a=='')
z='';
a is a DOM element, and so it will always be != 0 as the != operator will coerce it to a string, and then to a number, and that number will be != 0.
You probably wanted to use the .value property:
var a = document.getElementById('t1').value;
But you'd still have a problem: The value of an input is always a string. In JavaScript, the == and != operators do type coercion, and "" is == 0. So your third statement, z='', will never be reached.
You can use the strict equality operators to figure out what's going on:
var a = document.getElementById('t1').value;
var z = document.getElementById('d1');
if (a === "") { // <== Note! === rather than ==
z.value = "";
} else {
a = +a; // Convert to number intentionally
if (a != 0) {
var y = a * 100;
y = y || 0;
z.value = y.toFixed(2);
} else if (a == 0) {
z.value = "0";
}
}
The strict equality (===) and inequality (!==) operators don't do type coercion, so although "" == 0 is true, "" === 0 is false.
That line where I converted to a number:
a = +a;
...is only one of the many options available. Using +str to convert to a number is the strictest way, but you don't have direct control over the number base. You could also use:
a = parseInt(a, 10); // If you're expecting an integer, or
a = parseFloat(a); // If it may have a fractional portion
...assuming you want base 10 (decimal), but note that they ignore trailing characters, and so parseInt("123laksdjflk", 10) is 123. In contrast, +str (or Number(str)) will say that's Nan because they consider the entire string, not just the first part.

Categories

Resources