Math.max.apply(null, arr); [duplicate] - javascript

This question already has answers here:
How does the Math.max.apply() work?
(5 answers)
Closed 5 years ago.
How does
Math.max.apply(null, arr);
exactly work?
Suppose
var arr = [45,25,4,65] ;
will it compare 'null' and '45' and return maximum number between two adjacent e.g. 45?
After comparing will it again compare returned number and next array number e.g. 25 and return the max number?
And how is the calculation done internally? It is the same way, I think.

The first argument of apply is what will be this for the function.
Here it does not matter as this function does not necessit a specific this value. It could matter in some other cases for instance:
var foo = {
b: true,
func: function() {
return this.b;
}
};
var bar = { b : false };
foo.func(); // true
foo.func.apply(bar); // false

It's equal to
Math.max(...arr);
and that's equal to:
Math.max(45, 25, 4, 65);
How it works internally is then up to the browsers / parsers native implementation. In js it might be:
Math.max = (...args) => {
let max = - Infinity;
for(const number of args)
if(number > max) max = number;
return max;
};

Related

Get min and max value of an array of strings in Javascript [duplicate]

This question already has answers here:
convert string array to integer array
(4 answers)
Find the min/max element of an array in JavaScript
(58 answers)
remove first element from array and return the array minus the first element
(7 answers)
Closed 8 months ago.
I have this array and it is formatted as string:
['identifier','6.35', '2.72', '11.79', '183.25']
The first item is always 'identifier' so must be filtered out.
What I need in this example as output is:
MaxValue = 183.25
MinValue = 2.72
What would be a clean and fast way to achieve this? My arrays can contain a lot of data.
You can to start by filtering out anything that is not numeric. You can then find the min and max as an aggregation. You could also optimize this by checking for a numeric during the aggregation to save scanning over the array once upfront):
const input = ['identifier','6.35', '2.72', '11.79', '183.25']
const result = input.filter( x => !isNaN(x)).reduce( (acc, x) => {
acc.max = Math.max(acc.max,x);
acc.min = Math.min(acc.min,x);
return acc;
}, {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY})
console.log(result);
Or if you prefer you can pass the resulting array to the Math.min and Math.max functions
const input = ['identifier','6.35', '2.72', '11.79', '183.25']
const nums = input.filter( x => !isNaN(x));
console.log(Math.max(...nums));
console.log(Math.min(...nums));
Scan the array only once
let data = ["identifier", "6.35", "2.72", "11.79", "183.25"];
function minMax(data) {
let min = Infinity;
let max = -Infinity;
for (let s of data) {
let n = Number.parseFloat(s);
if (Number.isNaN(n)) continue;
if (min > n) min = n;
if (max < n) max = n;
}
return [min, max];
}
console.log(minMax(data));

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/

Check if a string is sorted in javascript

please i want to check if this string is sorted?
var myBucket = "1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y";
1D=One Day 2D=2 Day ...
1W=1 Week
1M=1 Months 18M=18 Months
1Y=1 years
like 1D<2D<1W<3W<1M<10M<1Y<18M<2Y ...
How can i check this?
Thank you in advance.
I suggest to match a number and the length indicator. Then loop over with Array#every and split the part into number and length indicator. With a hash table for the length, you could calculate the length and test it with the last value before.
If greater, then proceed, else leave the loop and get false.
If the loop iterates over all elements, and the callback returns true, then it return true.
var myBucket = '1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y',
values = { D: 1, W: 7, M: 30, Y: 365 },
result = myBucket.match(/\d+[DWMY]/g).every(function (a, i) {
var p = a.split(/(?=[DWMY])/),
value = p[0] * (values[p[1]] || 0);
if (value > this.last) {
this.last = value;
return true;
}
}, { last: -Infinity });
console.log(result);

Tail function in javascript [duplicate]

This question already has answers here:
Variadic curried sum function
(19 answers)
Closed 7 years ago.
I want to make a function which adds arguments. Invoking this function should be
functionAdd(2)(3)(4)...(n);
And the result 2+3+4...+n
I'm trying this
function myfunction(num){
var summ =+ num;
if(num !== undefined){
return myfunction(summ);
}
};
But it doesn't works, an error of ovwerflow. And I don't understand where I should out from this function;
You can use the .valueOf to do the trick:
function myfunction(sum){
var accum = function(val) {
sum += val;
return accum;
};
accum.valueOf = function() {
return sum;
};
return accum(0);
};
var total = myfunction(1)(2)(3)(4);
console.log(total); // 10
JSFiddle: http://jsfiddle.net/vdkwhxrL/
How it works:
on every iteration you return a reference to the accumulator function. But when you request for the result - the .valueOf() is invoked, that returns a scalar value instead.
Note that the result is still a function. Most importantly that means it is not copied on assignment:
var copy = total
var trueCopy = +total // explicit conversion to number
console.log(copy) // 10 ; so far so good
console.log(typeof copy) // function
console.log(trueCopy) // 10
console.log(typeof trueCopy) // number
console.log(total(5)) // 15
console.log(copy) // 15 too!
console.log(trueCopy) // 10
If last call can be without arguments:
function add(value) {
var sum = value;
return function add(value) {
if(typeof value === 'number') {
sum += value
return add
} else {
return sum
}
}
}
console.log(add(1)(2)(3)(0)()) // 6

Sum of array elements returns NaN [duplicate]

This question already has answers here:
Object returning NaN when sum values
(3 answers)
Closed 8 years ago.
I have the following code
var Arr = [-1,3,-4,5,1,-6,2,1];
function solution ( A ) {
var sum;
var len = A.length;
for ( var key in A ) {
sum += +(parseInt(A[key]));
}
return sum;
}
solution( Arr );
and it returns NaN. Can someone help me?
Thanks!
You never initialize sum, so it starts undefined.
undefined + number = NaN
undefined + "any number" is always NaN.
Declare sum with a starting value of 0. (aka: initialize it)
var sum = 0;
Also, it's a good idea to use a radix in parseInt:
parseInt(A[key], 10)
This makes sure parseInt always tries to interpret A[key] as a decimal number.
Here is the working version of your code
function solution ( A ) {
var sum = 0;
var len = A.length;
for ( key in A ) {
sum += parseInt(A[key], 10);
}
return sum;
}
You should initialize sum also your +(parseInt(A[key])) has the same effect as parseInt(A[key])

Categories