Javascript assiging multiple values to `ternary` operator - javascript

How to assign multiple values to ternary operator? is that not possible? I tried like this, but getting error:
size === 3 ? ( var val1=999, var val2=100; ) : 0;
and
size === 3 ? ( var val1=999; var val2=100; ) : 0;
above both approach throws error. how to set both var val1 and var val2;
I can directly declare it. But I would like to know the ternary operator approach here.

var size=3;
var val1=null;
var val2=null;
size === 3 ? ( val1=999,val2=100 ) : 0;
console.log(val1,val2)

Its a syntax error .You could use like this separate call
var size=3;
var val1 = size === 3 ? 999 : 0;
var val2 = size === 3 ? 100 : 0;
console.log(val1,val2)

You can do like this
var val1 = 0,
val2 = 0,
size = 3;
3 === size ? function() {
val1 = 999;
val2 = 100
}() : 0;
console.log(val1, val2);

Use an if statement.
var val1;
var val2;
if (size === 3) {
val1 = 999;
val2 = 100;
}
Whilst D-reaper's answer answers your question, really your question is not the right thing to ask. (Additionally eval is useful very very occasionally but is otherwise considered "evil" as it prevents various JavaScript engine optimisations and opens security holes like XSS if used on stored user input data).
Ternary operators are useful when you're using them to assign to another variable like:
var val1 = size === 3 ? 999 : 0;
In your example the fact you do no assignment, the first expression does not intend to return a value and the second value of 0 is ignored and therefore redundant is a very strong code smell they should alert you to there being a better easier way of doing what you want.

The syntax of ternary operator is
condition ? expr1 : expr2
var val1=999; var val2=100; is a valid declaration (var val1=999, var val2=100; is not), but NOT an expression. So you can't use them the way you've done it in your code. However, you can make it into an expression by using the eval function like so:
size === 3 ? eval('var val1=999; var val2=100;') : 0;
Of course, as the others have pointed out. Using eval is the wrong approach to take. I am showing you how it could be done for the sake of answering your question.

Here is my try: it works fine for me:
createDigit : function( size ) {
var val1, val2;
size === 3 ? ( val1=999, val2=100 ) : size === 2 ? ( val1=99, val2=10 ) : 0;
//generates only 3 digit values
return Math.floor( Math.random()*(val1-val2+1 )) + val2;
},

I see what you are trying to do, you can use Math.pow() to generate numbers instead of checking on size manually. I have put down two methods below : createDigit is mine which can generate numbers for any size given using Math.pow() and createDigitBuggy is yours which will just generate numbers for size 2 and 3 and rest will be NaN.
// Improved version
const createDigit = (size) => {
if (size > 0) {
const val1 = Math.pow(10, size) - 1
const val2 = Math.pow(10, size - 1)
return Math.floor(Math.random() * (val1 - val2 + 1)) + val2
}
return 0
}
// Old buggy version
const createDigitBuggy = (size) => {
var val1, val2
size === 3 ? (val1 = 999, val2 = 100) : size === 2 ? (val1 = 99, val2 = 10) : 0
return Math.floor(Math.random() * (val1 - val2 + 1)) + val2
}
console.log(createDigitBuggy(1)) // prints NaN
console.log(createDigitBuggy(2)) // prints number
console.log(createDigitBuggy(3)) // prints number
console.log(createDigitBuggy(4)) // prints NaN
console.log(createDigit(1)) // prints number
console.log(createDigit(2)) // prints number
console.log(createDigit(3)) // prints number
console.log(createDigit(4)) // prints number

Related

in Javascript, exist a function that return only the fractional part of a number, like Math dot something.... ? How can I get it? [duplicate]

I have a floating point number:
var f = 0.1457;
Or:
var f = 4.7005
How do I get just the fraction remainder as integer?
I.e. in the first example I want to get:
var remainder = 1457;
In the second example:
var remainder = 7005;
function frac(f) {
return f % 1;
}
While this is not what most people will want, but TS asked for fract as integer, here it is:
function fract(n){ return Number(String(n).split('.')[1] || 0); }
fract(1.23) // = 23
fract(123) // = 0
fract(0.0008) // = 8
This will do it (up to the 4 digits that you want, change the multipler (10000) to larger or smaller if you want smaller or larger number):
Math.ceil(((f < 1.0) ? f : (f % Math.floor(f))) * 10000)
parseInt(parseFloat(amount).toString().split('.')[1], 10)
You can subtract the floor of the number, giving you just the fractional part, and then multiply by 10000, i.e.:
var remainder = (f-Math.floor(f))*10000;
I would argue that, assuming we want to display these values to the user, treating these numbers as strings would be the best approach. This gets round the issue of fractional values such as 0.002.
I came accross this issue when trying to display prices with the cents in superscript.
let price = 23.43; // 23.43
let strPrice = price.toFixed(2) + ''; // "23.43"
let integer = strPrice.split(".")[0] // "23"
let fractional = strPrice.split(".")[1] // "43"
This also depends on what you want to do with the remainder (as commenters already asked). For instance, if the base number is 1.03, do you want the returned remainder as 3 or 03 -- I mean, do you want it as a number or as a string (for purposes of displaying it to the user). One example would be article price display, where you don't want to conver 03 to 3 (for instance $1.03) where you want to superscript 03.
Next, the problem is with float precision. Consider this:
var price = 1.03;
var frac = (price - Math.floor(price))*100;
// frac = 3.0000000000000027
So you can "solve" this by slicing the string representation without multiplication (and optional zero-padding) in such cases. At the same time, you avoid floating precision issue. Also demonstrated in this jsfiddle.
This post about floating precision might help as well as this one.
var strNumber = f.toString();
var remainder = strNumber.substr(strNumber.indexOf('.') + 1, 4);
remainder = Number(reminder);
Similar method to Martina's answer with a basic modulo operation but solves some of the issues in the comments by returning the same number of decimal places as passed in.
Modifies a method from an answer to a different question on SO which handles the scientific notation for small floats.
Additionally allows the fractional part to be returned as an integer (ie OP's request).
function sfract(n, toInt) {
toInt = false || toInt;
let dec = n.toString().split('e-');
let places = dec.length > 1
? parseInt(dec[1], 10)
: Math.floor(n) !== n ? dec[0].split('.')[1].length : 0;
let fract = parseFloat((n%1).toFixed(places));
return toInt ? fract * Math.pow(10,places) : fract;
};
Tests
function sfract(n, toInt) {
toInt = false || toInt;
let dec = n.toString().split('e-');
let places = dec.length > 1
? parseInt(dec[1], 10)
: Math.floor(n) !== n ? dec[0].split('.')[1].length : 0;
let fract = parseFloat((n%1).toFixed(places));
return toInt ? fract * Math.pow(10,places) : fract;
};
console.log(sfract(0.0000005)); // 5e-7
console.log(sfract(0.0000005, true)); // 5
console.log(sfract(4444)); // 0
console.log(sfract(4444, true)); // 0
console.log(sfract(44444.0000005)); // 5e-7
console.log(sfract(44444.00052121, true)); // 52121
console.log(sfract(34.5697)); // 0.5697
console.log(sfract(730.4583333333321, true)); // 4583333333321
#Udara Seneviratne
const findFraction = (num) => {
return parseInt( // 5.---------------- And finally we parses a "string" type and returns an integer
// 1. We convert our parameter "num" to the "string" type (to work as with an array in the next step)
// result: "1.012312"
num.toString()
// 2. Here we separating the string as an array using the separator: " . "
// result: ["1", "012312"]
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
.split('.')
// 3. With help a method "Array.splice" we cut the first element of our array
// result: ["012312"]
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
.splice(1.1)
// 4. With help a method "Array.shift" we remove the first element from an array and returns that
// result: 012312 (But it's still the "string" type)
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
.shift()
)
}
// Try it
console.log("Result is = " + findFraction (1.012312))
// Type of result
console.log("Type of result = " + typeof findFraction (1.012312))
// Some later operation
console.log("Result + some number is = " + findFraction (1.012312) + 555)

Quadratic Expression. Bugs

I am a beginner in JavaScript programming and this is my first project. I am trying to find the factors of a quadratic expression using the standard factorization method. I have explained the logic I used in the code as a comment at the beginning of the main JavaScript function and I have also listed the bugs I have detected so far at the end of the code. I depended solely on my logic based on previous exercises I have done to write this code, so I am hoping to learn a lot from your corrections. I don't know where the bugs are coming from in the code. I would be very grateful if you can help me figure out any. Thank you.
<!DOCTYPE html>
<html>
<head>
<title>Factorization of Quadratic Expression</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div id="box">
<div id="inner">
<p>Quadratic Equation <span id="warning">MUST</span> be in this format
<span id="format">ax<sup>2</sup> + bx + c</span></p>
<p>Use the caret symbol (<span id="caret">^</span>) for exponent, e.g x^2</p>
<input type="text" placeholder="Enter quadratic equation" id="equation" required/><br/>
<br/>
<button id="solve">Answer</button>
<p id="solution"></p>
</div>
</div>
<script type="text/javascript">
// get button and paragraph to display solution
let solution = document.getElementById('solution');
let solve = document.getElementById('solve');
// solve quadratic equation
solve.onclick = function() {
/* This is the main function of the code that finds the factors a quadratic expression.
I assume you already have an understanding of quadratic expressions but I will
explain
the logic I used in the code. Assuming you have a quadratic expression f(x),
f(x) = x^2 - 4x + 4
I first multiplied the coefficient of x^2 which is +1 in this case with the constant
which
is +4. Then I find two numbers whose product gives the value of the constant +4 and
whose
sum gives the value of the coefficient of x which is -4. The numbers are -2 and -2.
Then I substitute the numbers with the value of the coefficient of x adding the
literal.
f(x) = x^2 - 2x - 2x + 4
Next is grouping the first two quadratic coefficients and the last two using
parentheses.
f(x) = (x^2 - 2x) - (2x - 4)
The arithmetic symbol of the constant changes because once you expand it will give
you the former expression.
Next is to finding the greatest common divisors of both groups and simplify.
f(x) = x(x - 2) - 2(x - 2)
Next is getting the common factors.
f(x) = (x - 2)(x - 2) // Final answer
Last line of code outputs the answer and it is the biggest challenge I am having
because it seems I can only display a specific arithmetic symbol '+' (I chose to use
this because I wrote the code using an all positive quadritic expression) in this
case though it varies depending on the quadratic expression, like the one I used in
this comment. */
// get expression from input
let equation = document.getElementById('equation').value;
// validate expression (Only did this for fun and to get the feel of a real-world
project)
// if input was an empty string
if(equation === '') {
solution.innerHTML = 'Error: No expression found! Please fill out the input field';
}
// if a symbol is missing or is there is none
else if((equation.match(/(\+|\-)/g) === null) || (equation.match(/(\+|\-)/g).length < 2))
{
solution.innerHTML = 'Error: Missing symbol in expression';
}
// if the expression is not in the specified format
else if((equation.match(/\s/g).length < 2) || (equation.match(/\s/g).length > 2)) {
solution.innerHTML = 'Error: Missing or excess whitespace character in expression';
}
// if the exponent of x is not 2
else if(equation[equation.indexOf('^') + 1] !== 2) {
solution.innerHTML = 'Error: Exponent of x must be equal to 2';
}
// none of these validations work by the way not sure why
// get coefficient of x^2, x and the constant in the equation from input
array = equation.trim().split(''),
sign1 = array.indexOf('+'),
sign2 = array.lastIndexOf('+'),
getCoefficient_x2 = array.slice(0, array.indexOf(sign1 !== -1 ? '+' : '-') +
2).join(''),
getCoefficient_x = array.slice(array.indexOf(sign1 !== -1 ? '+' : '-') + 2,
array.lastIndexOf('+') - 1).join(''),
getConstant = array.slice(array.lastIndexOf(sign2 !== -1? '+' : '-') + 2).join(''),
cox2 = parseInt(getCoefficient_x2) || 1,
cox = parseInt(getCoefficient_x) || 1,
c = parseInt(getConstant);
// solving quadratic equation
let product = cox2 * c,
sum = cox,
factors = getFactors(product),
sum_product = [],
_gcd = 0,
gcd_ = 0,
cfactor = [];
// get factors whose product is equal to the constant and whose sum is equal to
coefficient of x
for(let i = 0; i < factors.length; i++) {
for(let j = 0; j < factors.length; j++) {
if((factors[i] * factors[j] === product) && (factors[i] + factors[j] === sum)) {
sum_product = [factors[j], factors[i]];
}
}
}
// grouping
// get greatest common divisor of both groups
_gcd = gcd(cox2, sum_product[0]);
gcd_ = gcd(sum_product[1], c);
// finding the common factors of the expression
/* since the computer never makes a mistake I will only factor the first grouping as this
will determine the other. */
cfactor.push(cox2 / _gcd, sum_product[0] / _gcd);
// expression of factorization is given as:
solution.innerHTML = `(${_gcd > 1 ? _gcd : ''}x + ${gcd_})\
(${cfactor[0] > 1 ? cfactor[0] : ''}x + ${cfactor[1]})`;
}
// function to get all negative and positive factors of a number
function getFactors(number) {
var factors = [],
i = 0;
if(number === undefined) number = 0;
for(i = -number; i <= number; i++) {
if(number % i === 0) factors.push(i);
}
return factors;
}
// function to get the greatest common divisor of two numbers
function gcd(num1, num2) {
var numFac = [], gcd, maxNum = Math.max(num1, num2);
for(let n = 1; n <= maxNum; n++) {
if(num1 % n == 0 && num2 % n == 0) {
numFac.push(n);
}
}
return Math.max(...numFac);
}
// Bugs
/* (1) Outputs an unexpected value if the coefficient of x is greater than the constant.
(2) Outputs an unexpected value if the expression uses a negative number.
(3) Outputs an unexpected value if coefficient of x and the constant have no common
factors to determine the the sum and product respectively.
(4) None of the validation codes works.
(5) I am not sure how I can vary the signs of the symbol depending on the give expression.
*/
</script>
</body>
</html>
About the 4th bug: Your validations are working, the inner content of solution is being modified, but your final answer is overwriting it. You could add a boolean variable valid = false if one of your validations returns an error, and before changing the innerHTML of solution for the final answer, check if valid = true, if it is not, don't print your final answer.
Like this:
var valid = true;
if (equation === '') {
solution.innerHTML = 'Error: No expression found! Please fill out the input field';
valid = false;
}
// if a symbol is missing or is there is none
else if ((equation.match(/(\+|\-)/g) === null) || (equation.match(/(\+|\-)/g).length < 2)) {
solution.innerHTML = 'Error: Missing symbol in expression';
valid = false;
}
// if the expression is not in the specified format
else if ((equation.match(/\s/g).length < 2) || (equation.match(/\s/g).length > 2)) {
solution.innerHTML = 'Error: Missing or excess whitespace character in expression';
valid = false;
}
// if the exponent of x is not 2
else if (equation[equation.indexOf('^') + 1] !== 2) {
solution.innerHTML = 'Error: Exponent of x must be equal to 2';
valid = false;
}
And in your final answer:
if (valid) {
solution.innerHTML = `(${_gcd > 1 ? _gcd : ''}x + ${gcd_})\
(${cfactor[0] > 1 ? cfactor[0] : ''}x + ${cfactor[1]})`;
}
Thank very much. I understand. I'm enlightened, it slipped my mind that the code
will continue to the next line even if one of the if statements is true. I might have thought I was returning the error message. Thanks again.

Javascript countdown - always 2 numbers [duplicate]

This question already has answers here:
How can I pad a value with leading zeros?
(76 answers)
Closed 3 years ago.
In JavaScript, I need to have padding.
For example, if I have the number 9, it will be "0009". If I have a number of say 10, it will be "0010". Notice how it will always contain four digits.
One way to do this would be to subtract the number minus 4 to get the number of 0s I need to put.
Is there was a slicker way of doing this?
ES2017 Update
You can use the built-in String.prototype.padStart()
n = 9;
String(n).padStart(4, '0'); // '0009'
n = 10;
String(n).padStart(4, '0'); // '0010'
Not a lot of "slick" going on so far:
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
When you initialize an array with a number, it creates an array with the length set to that value so that the array appears to contain that many undefined elements. Though some Array instance methods skip array elements without values, .join() doesn't, or at least not completely; it treats them as if their value is the empty string. Thus you get a copy of the zero character (or whatever "z" is) between each of the array elements; that's why there's a + 1 in there.
Example usage:
pad(10, 4); // 0010
pad(9, 4); // 0009
pad(123, 4); // 0123
pad(10, 4, '-'); // --10
function padToFour(number) {
if (number<=9999) { number = ("000"+number).slice(-4); }
return number;
}
Something like that?
Bonus incomprehensible-but-slicker single-line ES6 version:
let padToFour = number => number <= 9999 ? `000${number}`.slice(-4) : number;
ES6isms:
let is a block-scoped variable (as opposed to var’s functional scoping)
=> is an arrow function that, among other things, replaces function and is prepended by its parameters
If an arrow function takes a single parameter, you can omit the parentheses (hence number =>)
If an arrow function body has a single line that starts with return, you can omit the braces and the return keyword and simply use the expression
To get the function body down to a single line, I cheated and used a ternary expression
Try:
String.prototype.lpad = function(padString, length) {
var str = this;
while (str.length < length)
str = padString + str;
return str;
}
Now test:
var str = "5";
alert(str.lpad("0", 4)); //result "0005"
var str = "10"; // note this is string type
alert(str.lpad("0", 4)); //result "0010"
DEMO
In ECMAScript 2017 , we have new method padStart and padEnd which has below syntax.
"string".padStart(targetLength [,padString]):
So now we can use
const str = "5";
str.padStart(4, "0"); // "0005"
Funny, I recently had to do this.
function padDigits(number, digits) {
return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
}
Use like:
padDigits(9, 4); // "0009"
padDigits(10, 4); // "0010"
padDigits(15000, 4); // "15000"
Not beautiful, but effective.
You did say you had a number-
String.prototype.padZero= function(len, c){
var s= '', c= c || '0', len= (len || 2)-this.length;
while(s.length<len) s+= c;
return s+this;
}
Number.prototype.padZero= function(len, c){
return String(this).padZero(len,c);
}
You could do something like this:
function pad ( num, size ) {
return ( Math.pow( 10, size ) + ~~num ).toString().substring( 1 );
}
Edit: This was just a basic idea for a function, but to add support for larger numbers (as well as invalid input), this would probably be better:
function pad ( num, size ) {
if (num.toString().length >= size) return num;
return ( Math.pow( 10, size ) + Math.floor(num) ).toString().substring( 1 );
}
This does 2 things:
If the number is larger than the specified size, it will simply return the number.
Using Math.floor(num) in place of ~~num will support larger numbers.
This is not really 'slick' but it's faster to do integer operations than to do string concatenations for each padding 0.
function ZeroPadNumber ( nValue )
{
if ( nValue < 10 )
{
return ( '000' + nValue.toString () );
}
else if ( nValue < 100 )
{
return ( '00' + nValue.toString () );
}
else if ( nValue < 1000 )
{
return ( '0' + nValue.toString () );
}
else
{
return ( nValue );
}
}
This function is also hardcoded to your particular need (4 digit padding), so it's not generic.
For fun, instead of using a loop to create the extra zeros:
function zeroPad(n,length){
var s=n+"",needed=length-s.length;
if (needed>0) s=(Math.pow(10,needed)+"").slice(1)+s;
return s;
}
Since you mentioned it's always going to have a length of 4, I won't be doing any error checking to make this slick. ;)
function pad(input) {
var BASE = "0000";
return input ? BASE.substr(0, 4 - Math.ceil(input / 10)) + input : BASE;
}
Idea: Simply replace '0000' with number provided... Issue with that is, if input is 0, I need to hard-code it to return '0000'. LOL.
This should be slick enough.
JSFiddler: http://jsfiddle.net/Up5Cr/

Javascript Function defaulting to wrong answer (I think)

Hi can somebody tell me why the output to my function defaults to even when you insert over 17 numbers? It's probably super simple, please go easy on me!
function oddOrEven(number) {
var number = document.getElementById('number').value;
if(number % 2 != 0) {
document.getElementById('demo').innerHTML = "Odd";
}
else {
document.getElementById('demo').innerHTML = "Even";
}
if (number.length === 0) {
document.getElementById('demo').innerHTML = "Odd / Even";
}
}
You can simplify this whole thing. If you are always grabbing the input with id 'number' you don't need to pass a param, and then after a simple test you can inline the answer you want:
function oddOrEven(){
var val = document.getElementById('number').value;
var number = parseInt(val, 10);
// if it's not a valid number, you'll have NaN here which is falsy
if (number) {
document.getElementById('demo').innerHTML = (number % 2) ? "Even" : "Odd";
}
}
All that said, I just caught that you're talking about 17 digits (thanks to #JJJ's comment) rather than using the function more than once. The problem in this case is that JS integers have a size limit. If you parse anything larger it returns a number you're not going to expect. There are a lot of discussion of general handling of very large numbers here: http://2ality.com/2012/07/large-integers.html, but for your modulus problem you could take the last digit and check if that's odd or even like so:
function oddOrEven(){
var val = document.getElementById('number').value;
var number = parseInt(val, 10);
// if it's not a valid number, you'll have NaN here which is falsy
if (number) {
var lastDigit = val[val.length-1];
document.getElementById('demo').innerHTML = (parseInt(lastDigit, 10) % 2) ? "Even" : "Odd";
}
}

What's the purpose of the Infinity property?

I accidentally faced an Infinity property in JavaScript and wondered where in the world it can be used? Any real life example please.
You can use it if you don't know what the minimum value of an array or also a mathematical-function is like this:
var minimum = Infinity;
var i = 0;
for(i = 0; i < array.length; i++) {
if(array[i] < minimum) {
// new minimum found
minimum = array[i];
}
}
alert("Minimum: " + minimum);
Here is another real life example:
var x = +prompt('Enter x:'),
y = +prompt('Enter y:'),
value = Math.pow(x, y);
if (value === Infinity || value === -Infinity) {
console.log('The value is too large!');
}
As an example, if the entered values are 1e100 and 100, the power method returns Infinity.
I'm assuming you're asking about why there's an Infinity global property, not why there's a concept of having infinities in the first place, which is another matter.
It allows easy comparison with the Infinity value itself, where you get it from some arithmetic:
function inv(x) {
return x * 100000000000;
}
inv(1e999) === Infinity;
This is especially useful as 1 / 0 is not equal to Infinity in mathematics, so it's not obvious that you can use 1 / 0.
If you want a numeric comparison to always return true, and you're using a variable, you can set the variable to Infinity to always force the condition to be true. Take this example:
var a = Infinity; // some number from elsewhere
var arr = [];
function foo(maxLen) {
if (arr.length < maxLen) arr.push(1);
}
foo(a); // you can't change the function
This could be useful in cases where you can't change the comparison statement used.

Categories