Avoiding repetition using higher order functions in JS? - javascript

How to write this snippet more functionality by avoiding repetitions of function creation like this in JavaScript? Just to give a context, I am trying find if the movement from current value to final value has already been achieved.. deltaValue is positive if the movement is towards a higher value and negative if its towards a lower value.
if (deltaValue > 0) {
maxPossibleValue = function(current, final) {
return current > final ? final : current;
}
} else {
maxPossibleValue = function(current, final) {
return current < final ? final : current;
}
}
Assuming there existed < and > as functions, lt and gt in JavaScript, I could have just evaluated this with a single function where predicate is lt and gt dealing with higher order functions. However there are no such functions natively in JS, so is the above method the only way?
maxPossibleValue = function(predicate) {
return function(c, f) {
return predicate(c, f) ? c : f }
}
This can be thought as just templating the required predicate function and returning a new function. I have seen such patterns in Scheme.

#Nina's answer points you in the right direction but Math.max and Math.min are not predicates. And the answer is overly complicated.
I see no reason why the answer should be harder to follow than this
function calculateValue(delta, final, current) {
return (delta > 0 ? Math.min : Math.max)(final, current);
}
calculateValue(-1, 5, 10); // 10
calculateValue(1, 5, 10); // 5

You have already a mechanism for your requirement, Math.min and Math.max.
The code looks like this, but maxPossibleValue is missleading
var maxPossibleValue = function (predicate) {
return function (c, f) {
return predicate(c, f)
}
},
comparer = maxPossibleValue(deltaValue > 0 ? Math.min : Math.max);
Working example:
var deltaValue = -1;
var maxPossibleValue = function (predicate) {
return function (c, f) {
return predicate(c, f)
}
},
comparer = maxPossibleValue(deltaValue > 0 ? Math.min : Math.max);
document.write(comparer(2, 8));

Related

How to get median and quartiles/percentiles of an array in JavaScript (or PHP)?

This question is turned into a Q&A, because I had struggle finding the answer, and think it can be useful for others
I have a JavaScript array of values and need to calculate in JavaScript its Q2 (50th percentile aka MEDIAN), Q1 (25th percentile) and Q3 (75th percentile) values.
I updated the JavaScript translation from the first answer to use arrow functions and a bit more concise notation. The functionality remains mostly the same, except for std, which now computes the sample standard deviation (dividing by arr.length - 1 instead of just arr.length)
// sort array ascending
const asc = arr => arr.sort((a, b) => a - b);
const sum = arr => arr.reduce((a, b) => a + b, 0);
const mean = arr => sum(arr) / arr.length;
// sample standard deviation
const std = (arr) => {
const mu = mean(arr);
const diffArr = arr.map(a => (a - mu) ** 2);
return Math.sqrt(sum(diffArr) / (arr.length - 1));
};
const quantile = (arr, q) => {
const sorted = asc(arr);
const pos = (sorted.length - 1) * q;
const base = Math.floor(pos);
const rest = pos - base;
if (sorted[base + 1] !== undefined) {
return sorted[base] + rest * (sorted[base + 1] - sorted[base]);
} else {
return sorted[base];
}
};
const q25 = arr => quantile(arr, .25);
const q50 = arr => quantile(arr, .50);
const q75 = arr => quantile(arr, .75);
const median = arr => q50(arr);
After searching for a long time, finding different versions that give different results, I found this nice snippet on Bastian Pöttner's web blog, but for PHP. For the same price, we get the average and standard deviation of the data (for normal distributions)...
PHP Version
//from https://blog.poettner.de/2011/06/09/simple-statistics-with-php/
function Median($Array) {
return Quartile_50($Array);
}
function Quartile_25($Array) {
return Quartile($Array, 0.25);
}
function Quartile_50($Array) {
return Quartile($Array, 0.5);
}
function Quartile_75($Array) {
return Quartile($Array, 0.75);
}
function Quartile($Array, $Quartile) {
sort($Array);
$pos = (count($Array) - 1) * $Quartile;
$base = floor($pos);
$rest = $pos - $base;
if( isset($Array[$base+1]) ) {
return $Array[$base] + $rest * ($Array[$base+1] - $Array[$base]);
} else {
return $Array[$base];
}
}
function Average($Array) {
return array_sum($Array) / count($Array);
}
function StdDev($Array) {
if( count($Array) < 2 ) {
return;
}
$avg = Average($Array);
$sum = 0;
foreach($Array as $value) {
$sum += pow($value - $avg, 2);
}
return sqrt((1 / (count($Array) - 1)) * $sum);
}
Based on the author's comments, I simply wrote a JavaScript translation that will certainly be useful, because surprisingly, it is nearly impossible to find a JavaScript equivalent on the web, and otherwise requires additional libraries like Math.js
JavaScript Version
//adapted from https://blog.poettner.de/2011/06/09/simple-statistics-with-php/
function Median(data) {
return Quartile_50(data);
}
function Quartile_25(data) {
return Quartile(data, 0.25);
}
function Quartile_50(data) {
return Quartile(data, 0.5);
}
function Quartile_75(data) {
return Quartile(data, 0.75);
}
function Quartile(data, q) {
data=Array_Sort_Numbers(data);
var pos = ((data.length) - 1) * q;
var base = Math.floor(pos);
var rest = pos - base;
if( (data[base+1]!==undefined) ) {
return data[base] + rest * (data[base+1] - data[base]);
} else {
return data[base];
}
}
function Array_Sort_Numbers(inputarray){
return inputarray.sort(function(a, b) {
return a - b;
});
}
function Array_Sum(t){
return t.reduce(function(a, b) { return a + b; }, 0);
}
function Array_Average(data) {
return Array_Sum(data) / data.length;
}
function Array_Stdev(tab){
var i,j,total = 0, mean = 0, diffSqredArr = [];
for(i=0;i<tab.length;i+=1){
total+=tab[i];
}
mean = total/tab.length;
for(j=0;j<tab.length;j+=1){
diffSqredArr.push(Math.pow((tab[j]-mean),2));
}
return (Math.sqrt(diffSqredArr.reduce(function(firstEl, nextEl){
return firstEl + nextEl;
})/tab.length));
}
TL;DR
The other answers appear to have solid implementations of the "R-7" version of computing quantiles. Below is some context and another JavaScript implementation borrowed from D3 using the same R-7 method, with the bonuses that this solution is es5 compliant (no JavaScript transpilation required) and probably covers a few more edge cases.
Existing solution from D3 (ported to es5/"vanilla JS")
The "Some Background" section, below, should convince you to grab an existing implementation instead of writing your own.
One good candidate is D3's d3.array package. It has a quantile function that's essentially BSD licensed:
https://github.com/d3/d3-array/blob/master/src/quantile.js
I've quickly created a pretty straight port from es6 into vanilla JavaScript of d3's quantileSorted function (the second function defined in that file) that requires the array of elements to have already been sorted. Here it is. I've tested it against d3's own results enough to feel it's a valid port, but your experience might differ (let me know in the comments if you find a difference, though!):
Again, remember that sorting must come before the call to this function, just as in D3's quantileSorted.
//Credit D3: https://github.com/d3/d3-array/blob/master/LICENSE
function quantileSorted(values, p, fnValueFrom) {
var n = values.length;
if (!n) {
return;
}
fnValueFrom =
Object.prototype.toString.call(fnValueFrom) == "[object Function]"
? fnValueFrom
: function (x) {
return x;
};
p = +p;
if (p <= 0 || n < 2) {
return +fnValueFrom(values[0], 0, values);
}
if (p >= 1) {
return +fnValueFrom(values[n - 1], n - 1, values);
}
var i = (n - 1) * p,
i0 = Math.floor(i),
value0 = +fnValueFrom(values[i0], i0, values),
value1 = +fnValueFrom(values[i0 + 1], i0 + 1, values);
return value0 + (value1 - value0) * (i - i0);
}
Note that fnValueFrom is a way to process a complex object into a value. You can see how that might work in a list of d3 usage examples here -- search down where .quantile is used.
The quick version is if the values are tortoises and you're sorting tortoise.age in every case, your fnValueFrom might be x => x.age. More complicated versions, including ones that might require accessing the index (parameter 2) and entire collection (parameter 3) during the value calculation, are left up to the reader.
I've added a quick check here so that if nothing is given for fnValueFrom or if what's given isn't a function the logic assumes the elements in values are the actual sorted values themselves.
Logical comparison to existing answers
I'm reasonably sure this reduces to the same version in the other two answers (see "The R-7 Method", below), but if you needed to justify why you're using this to a product manager or whatever maybe the below will help.
Quick comparison:
function Quartile(data, q) {
data=Array_Sort_Numbers(data); // we're assuming it's already sorted, above, vs. the function use here. same difference.
var pos = ((data.length) - 1) * q; // i = (n - 1) * p
var base = Math.floor(pos); // i0 = Math.floor(i)
var rest = pos - base; // (i - i0);
if( (data[base+1]!==undefined) ) {
// value0 + (i - i0) * (value1 which is values[i0+1] - value0 which is values[i0])
return data[base] + rest * (data[base+1] - data[base]);
} else {
// I think this is covered by if (p <= 0 || n < 2)
return data[base];
}
}
So that's logically close/appears to be exactly the same. I think d3's version that I ported covers a few more edge/invalid conditions and includes the fnValueFrom integration, both of which could be useful.
The R-7 Method vs. "Common Sense"
As mentioned in the TL;DR, the answers here, according to d3.array's readme, all use the "R-7 method".
This particular implementation [from d3] uses the R-7 method, which is the default for the R programming language and Excel.
Since the d3.array code matches the other answers here, we can safely say they're all using R-7.
Background
After a little sleuthing on some math and stats StackExchange sites (1, 2), I found that there are "common sensical" ways of calculating each quantile, but that those don't typically mesh up with the results of the nine generally recognized ways to calculate them.
The answer at that second link from stats.stackexchange says of the common-sensical method that...
Your textbook is confused. Very few people or software define quartiles this way. (It tends to make the first quartile too small and the third quartile too large.)
The quantile function in R implements nine different ways to compute quantiles!
I thought that last bit was interesting, and here's what I dug up on those nine methods...
Wikipedia's description of those nine methods here, nicely grouped in a table
An article from the Journal of Statistics Education titled "Quartiles in Elementary Statistics"
A blog post at SAS.com called "Sample quantiles: A comparison of 9 definitions"
The differences between d3's use of "method 7" (R-7) to determine quantiles versus the common sensical approach is demonstrated nicely in the SO question "d3.quantile seems to be calculating q1 incorrectly", and the why is described in good detail in this post that can be found in philippe's original source for the php version.
Here's a bit from Google Translate (original is in German):
In our example, this value is at the (n + 1) / 4 digit = 5.25, i.e. between the 5th value (= 5) and the 6th value (= 7). The fraction (0.25) indicates that in addition to the value of 5, ¼ of the distance between 5 and 6 is added. Q1 is therefore 5 + 0.25 * 2 = 5.5.
All together, that tells me I probably shouldn't try to code something based on my understanding of what quartiles represent and should borrow someone else's solution.
Based on buboh's answer, which I have used for over a year, I have noticed some weird things for calculating the Q1 and Q3 when there are 2 numbers in the middle.
I have no clue why there is a rest value and how it is used, but by my understanding if you and up having 2 numbers in the middle you need to take the average of them to calculate the median. With that in mind I edited the function:
const asc = (arr) => arr.sort((a, b) => a - b);
const quantile = (arr, q) => {
const sorted = asc(arr);
let pos = (sorted.length - 1) * q;
if (pos % 1 === 0) {
return sorted[pos];
}
pos = Math.floor(pos);
if (sorted[pos + 1] !== undefined) {
return (sorted[pos] + sorted[pos + 1]) / 2;
}
return sorted[pos];
};

Is there a mechanism to loop x times in ES6 (ECMAScript 6) without mutable variables?

The typical way to loop x times in JavaScript is:
for (var i = 0; i < x; i++)
doStuff(i);
But I don't want to use the ++ operator or have any mutable variables at all. So is there a way, in ES6, to loop x times another way? I love Ruby's mechanism:
x.times do |i|
do_stuff(i)
end
Anything similar in JavaScript/ES6? I could kind of cheat and make my own generator:
function* times(x) {
for (var i = 0; i < x; i++)
yield i;
}
for (var i of times(5)) {
console.log(i);
}
Of course I'm still using i++. At least it's out of sight :), but I'm hoping there's a better mechanism in ES6.
Using the ES2015 Spread operator:
[...Array(n)].map()
const res = [...Array(10)].map((_, i) => {
return i * 10;
});
// as a one liner
const res = [...Array(10)].map((_, i) => i * 10);
Or if you don't need the result:
[...Array(10)].forEach((_, i) => {
console.log(i);
});
// as a one liner
[...Array(10)].forEach((_, i) => console.log(i));
Or using the ES2015 Array.from operator:
Array.from(...)
const res = Array.from(Array(10)).map((_, i) => {
return i * 10;
});
// as a one liner
const res = Array.from(Array(10)).map((_, i) => i * 10);
Note that if you just need a string repeated you can use String.prototype.repeat.
console.log("0".repeat(10))
// 0000000000
OK!
The code below is written using ES6 syntaxes but could just as easily be written in ES5 or even less. ES6 is not a requirement to create a "mechanism to loop x times"
If you don't need the iterator in the callback, this is the most simple implementation
const times = x => f => {
if (x > 0) {
f()
times (x - 1) (f)
}
}
// use it
times (3) (() => console.log('hi'))
// or define intermediate functions for reuse
let twice = times (2)
// twice the power !
twice (() => console.log('double vision'))
If you do need the iterator, you can use a named inner function with a counter parameter to iterate for you
const times = n => f => {
let iter = i => {
if (i === n) return
f (i)
iter (i + 1)
}
return iter (0)
}
times (3) (i => console.log(i, 'hi'))
Stop reading here if you don't like learning more things ...
But something should feel off about those...
single branch if statements are ugly — what happens on the other branch ?
multiple statements/expressions in the function bodies — are procedure concerns being mixed ?
implicitly returned undefined — indication of impure, side-effecting function
"Isn't there a better way ?"
There is. Let's first revisit our initial implementation
// times :: Int -> (void -> void) -> void
const times = x => f => {
if (x > 0) {
f() // has to be side-effecting function
times (x - 1) (f)
}
}
Sure, it's simple, but notice how we just call f() and don't do anything with it. This really limits the type of function we can repeat multiple times. Even if we have the iterator available, f(i) isn't much more versatile.
What if we start with a better kind of function repetition procedure ? Maybe something that makes better use of input and output.
Generic function repetition
// repeat :: forall a. Int -> (a -> a) -> a -> a
const repeat = n => f => x => {
if (n > 0)
return repeat (n - 1) (f) (f (x))
else
return x
}
// power :: Int -> Int -> Int
const power = base => exp => {
// repeat <exp> times, <base> * <x>, starting with 1
return repeat (exp) (x => base * x) (1)
}
console.log(power (2) (8))
// => 256
Above, we defined a generic repeat function which takes an additional input which is used to start the repeated application of a single function.
// repeat 3 times, the function f, starting with x ...
var result = repeat (3) (f) (x)
// is the same as ...
var result = f(f(f(x)))
Implementing times with repeat
Well this is easy now; almost all of the work is already done.
// repeat :: forall a. Int -> (a -> a) -> a -> a
const repeat = n => f => x => {
if (n > 0)
return repeat (n - 1) (f) (f (x))
else
return x
}
// times :: Int -> (Int -> Int) -> Int
const times = n=> f=>
repeat (n) (i => (f(i), i + 1)) (0)
// use it
times (3) (i => console.log(i, 'hi'))
Since our function takes i as an input and returns i + 1, this effectively works as our iterator which we pass to f each time.
We've fixed our bullet list of issues too
No more ugly single branch if statements
Single-expression bodies indicate nicely separated concerns
No more useless, implicitly returned undefined
JavaScript comma operator, the
In case you're having trouble seeing how the last example is working, it depends on your awareness of one of JavaScript's oldest battle axes; the comma operator – in short, it evaluates expressions from left to right and returns the value of the last evaluated expression
(expr1 :: a, expr2 :: b, expr3 :: c) :: c
In our above example, I'm using
(i => (f(i), i + 1))
which is just a succinct way of writing
(i => { f(i); return i + 1 })
Tail Call Optimisation
As sexy as the recursive implementations are, at this point it would be irresponsible for me to recommend them given that no JavaScript VM I can think of supports proper tail call elimination – babel used to transpile it, but it's been in "broken; will reimplement" status for well over a year.
repeat (1e6) (someFunc) (x)
// => RangeError: Maximum call stack size exceeded
As such, we should revisit our implementation of repeat to make it stack-safe.
The code below does use mutable variables n and x but note that all mutations are localized to the repeat function – no state changes (mutations) are visible from outside of the function
// repeat :: Int -> (a -> a) -> (a -> a)
const repeat = n => f => x =>
{
let m = 0, acc = x
while (m < n)
(m = m + 1, acc = f (acc))
return acc
}
// inc :: Int -> Int
const inc = x =>
x + 1
console.log (repeat (1e8) (inc) (0))
// 100000000
This is going to have a lot of you saying "but that's not functional !" – I know, just relax. We can implement a Clojure-style loop/recur interface for constant-space looping using pure expressions; none of that while stuff.
Here we abstract while away with our loop function – it looks for a special recur type to keep the loop running. When a non-recur type is encountered, the loop is finished and the result of the computation is returned
const recur = (...args) =>
({ type: recur, args })
const loop = f =>
{
let acc = f ()
while (acc.type === recur)
acc = f (...acc.args)
return acc
}
const repeat = $n => f => x =>
loop ((n = $n, acc = x) =>
n === 0
? acc
: recur (n - 1, f (acc)))
const inc = x =>
x + 1
const fibonacci = $n =>
loop ((n = $n, a = 0, b = 1) =>
n === 0
? a
: recur (n - 1, b, a + b))
console.log (repeat (1e7) (inc) (0)) // 10000000
console.log (fibonacci (100)) // 354224848179262000000
for (let i of Array(100).keys()) {
console.log(i)
}
Here is another good alternative:
Array.from({ length: 3}).map(...);
Preferably, as #Dave Morse pointed out in the comments, you can also get rid of the map call, by using the second parameter of the Array.from function like so:
Array.from({ length: 3 }, () => (...))
I think the best solution is to use let:
for (let i=0; i<100; i++) …
That will create a new (mutable) i variable for each body evaluation and assures that the i is only changed in the increment expression in that loop syntax, not from anywhere else.
I could kind of cheat and make my own generator. At least i++ is out of sight :)
That should be enough, imo. Even in pure languages, all operations (or at least, their interpreters) are built from primitives that use mutation. As long as it is properly scoped, I cannot see what is wrong with that.
You should be fine with
function* times(n) {
for (let i = 0; i < n; i++)
yield i;
}
for (const i of times(5)) {
console.log(i);
}
But I don't want to use the ++ operator or have any mutable variables at all.
Then your only choice is to use recursion. You can define that generator function without a mutable i as well:
function* range(i, n) {
if (i >= n) return;
yield i;
return yield* range(i+1, n);
}
times = (n) => range(0, n);
But that seems overkill to me and might have performance problems (as tail call elimination is not available for return yield*).
I think it is pretty simple:
[...Array(3).keys()]
or
Array(3).fill()
const times = 4;
new Array(times).fill().map(() => console.log('test'));
This snippet will console.log test 4 times.
Answer: 09 December 2015
Personally, I found the accepted answer both concise (good) and terse (bad). Appreciate this statement might be subjective, so please read this answer and see if you agree or disagree
The example given in the question was something like Ruby's:
x.times do |i|
do_stuff(i)
end
Expressing this in JS using below would permit:
times(x)(doStuff(i));
Here is the code:
let times = (n) => {
return (f) => {
Array(n).fill().map((_, i) => f(i));
};
};
That's it!
Simple example usage:
let cheer = () => console.log('Hip hip hooray!');
times(3)(cheer);
//Hip hip hooray!
//Hip hip hooray!
//Hip hip hooray!
Alternatively, following the examples of the accepted answer:
let doStuff = (i) => console.log(i, ' hi'),
once = times(1),
twice = times(2),
thrice = times(3);
once(doStuff);
//0 ' hi'
twice(doStuff);
//0 ' hi'
//1 ' hi'
thrice(doStuff);
//0 ' hi'
//1 ' hi'
//2 ' hi'
Side note - Defining a range function
A similar / related question, that uses fundamentally very similar code constructs, might be is there a convenient Range function in (core) JavaScript, something similar to underscore's range function.
Create an array with n numbers, starting from x
Underscore
_.range(x, x + n)
ES2015
Couple of alternatives:
Array(n).fill().map((_, i) => x + i)
Array.from(Array(n), (_, i) => x + i)
Demo using n = 10, x = 1:
> Array(10).fill().map((_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
> Array.from(Array(10), (_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
In a quick test I ran, with each of the above running a million times each using our solution and doStuff function, the former approach (Array(n).fill()) proved slightly faster.
I am late to the party, but since this question turns up often in search results, I would just like to add a solution that I consider to be the best in terms of readability while not being long (which is ideal for any codebase IMO). It mutates, but I'd make that tradeoff for KISS principles.
let times = 5
while( times-- )
console.log(times)
// logs 4, 3, 2, 1, 0
Array(100).fill().map((_,i)=> console.log(i) );
This version satisifies the OP's requirement for immutability. Also consider using reduce instead of map depending on your use case.
This is also an option if you don't mind a little mutation in your prototype.
Number.prototype.times = function(f) {
return Array(this.valueOf()).fill().map((_,i)=>f(i));
};
Now we can do this
((3).times(i=>console.log(i)));
+1 to arcseldon for the .fill suggestion.
Not something I would teach (or ever use in my code), but here's a codegolf-worthy solution without mutating a variable, no need for ES6:
Array.apply(null, {length: 10}).forEach(function(_, i){
doStuff(i);
})
More of an interesting proof-of-concept thing than a useful answer, really.
If you're willing to use a library, there's also lodash _.times or underscore _.times:
_.times(x, i => {
return doStuff(i)
})
Note this returns an array of the results, so it's really more like this ruby:
x.times.map { |i|
doStuff(i)
}
Afaik, there is no mechanism in ES6 similar to Ruby's times method. But you can avoid mutation by using recursion:
let times = (i, cb, l = i) => {
if (i === 0) return;
cb(l - i);
times(i - 1, cb, l);
}
times(5, i => doStuff(i));
Demo: http://jsbin.com/koyecovano/1/edit?js,console
In the functional paradigm repeat is usually an infinite recursive function. To use it we need either lazy evaluation or continuation passing style.
Lazy evaluated function repetition
const repeat = f => x => [x, () => repeat(f) (f(x))];
const take = n => ([x, f]) => n === 0 ? x : take(n - 1) (f());
console.log(
take(8) (repeat(x => x * 2) (1)) // 256
);
I use a thunk (a function without arguments) to achieve lazy evaluation in Javascript.
Function repetition with continuation passing style
const repeat = f => x => [x, k => k(repeat(f) (f(x)))];
const take = n => ([x, k]) => n === 0 ? x : k(take(n - 1));
console.log(
take(8) (repeat(x => x * 2) (1)) // 256
);
CPS is a little scary at first. However, it always follows the same pattern: The last argument is the continuation (a function), which invokes its own body: k => k(...). Please note that CPS turns the application inside out, i.e. take(8) (repeat...) becomes k(take(8)) (...) where k is the partially applied repeat.
Conclusion
By separating the repetition (repeat) from the termination condition (take) we gain flexibility - separation of concerns up to its bitter end :D
Advantages of this solution
Simplest to read / use (imo)
Return value can be used as a sum, or just ignored
Plain es6 version, also link to TypeScript version of the code
Disadvantages
- Mutation. Being internal only I don't care, maybe some others will not either.
Examples and Code
times(5, 3) // 15 (3+3+3+3+3)
times(5, (i) => Math.pow(2,i) ) // 31 (1+2+4+8+16)
times(5, '<br/>') // <br/><br/><br/><br/><br/>
times(3, (i, count) => { // name[0], name[1], name[2]
let n = 'name[' + i + ']'
if (i < count-1)
n += ', '
return n
})
function times(count, callbackOrScalar) {
let type = typeof callbackOrScalar
let sum
if (type === 'number') sum = 0
else if (type === 'string') sum = ''
for (let j = 0; j < count; j++) {
if (type === 'function') {
const callback = callbackOrScalar
const result = callback(j, count)
if (typeof result === 'number' || typeof result === 'string')
sum = sum === undefined ? result : sum + result
}
else if (type === 'number' || type === 'string') {
const scalar = callbackOrScalar
sum = sum === undefined ? scalar : sum + scalar
}
}
return sum
}
TypeScipt version
https://codepen.io/whitneyland/pen/aVjaaE?editors=0011
The simplest way I can think of for creating list/array within range
Array.from(Array(max-min+1), (_, index) => index+min)
I have another alternative
[...Array(30).keys()]
addressing the functional aspect:
function times(n, f) {
var _f = function (f) {
var i;
for (i = 0; i < n; i++) {
f(i);
}
};
return typeof f === 'function' && _f(f) || _f;
}
times(6)(function (v) {
console.log('in parts: ' + v);
});
times(6, function (v) {
console.log('complete: ' + v);
});
Generators? Recursion? Why so much hatin' on mutatin'? ;-)
If it is acceptable as long as we "hide" it, then just accept the use of a unary operator and we can keep things simple:
Number.prototype.times = function(f) { let n=0 ; while(this.valueOf() > n) f(n++) }
Just like in ruby:
> (3).times(console.log)
0
1
2
I wrapped #Tieme s answer with a helper function.
In TypeScript:
export const mapN = <T = any[]>(count: number, fn: (...args: any[]) => T): T[] => [...Array(count)].map((_, i) => fn())
Now you can run:
const arr: string[] = mapN(3, () => 'something')
// returns ['something', 'something', 'something']
I made this:
function repeat(func, times) {
for (var i=0; i<times; i++) {
func(i);
}
}
Usage:
repeat(function(i) {
console.log("Hello, World! - "+i);
}, 5)
/*
Returns:
Hello, World! - 0
Hello, World! - 1
Hello, World! - 2
Hello, World! - 3
Hello, World! - 4
*/
The i variable returns the amount of times it has looped - useful if you need to preload an x amount of images.
I am just going to put this here. If you are looking for a compact function without using Arrays and you have no issue with mutability/immutability :
var g =x=>{/*your code goes here*/x-1>0?g(x-1):null};
For me, this is the easiest answer to understand for many levels of developers
const times = (n, callback) => {
while (n) {
callback();
n--;
}
}
times(10, ()=> console.log('hello'))
It seems to me that the most correct answer (which is debatable) to this question is buried in a comment by Sasha Kondrashov and is also the most concise, using just two characters: "no". There is no functional alternative to a for-loop as nice as the syntax that Ruby has. We might want there to be one, but there just isn't.
It is not explicitly stated in the question, but I would argue any solution to the problem of 'looping N times' should not allocate memory, at least not proportional to N. That criterium would rule out most of the answers that are 'native to javascript'.
Other answers show implementations like the one in Ruby, which is fine, except that the question explicitly asks for a native javascript solution. And there is already a very decent hand-rolled solution in the question, arguably one of the most readable of all.

Sorting an array based on alphabets?

I need to sort an array based on Alphabets. I have tried sort() method of javascript, but it doesn't work since my array consists of numbers, lowercase letters and uppercase letters. Can anybody please help me out with this? Thanks
For e.g my array is:
[
"#Basil",
"#SuperAdmin",
"#Supreme",
"#Test10",
"#Test3",
"#Test4",
"#Test5",
"#Test6",
"#Test7",
"#Test8",
"#Test9",
"#a",
"#aadfg",
"#abc",
"#abc1",
"#abc2",
"#abc5",
"#abcd",
"#abin",
"#akrant",
"#ankur",
"#arsdarsd",
"#asdd",
"#ashaa",
"#aviral",
"#ayush.kansal",
"#chris",
"#dgji",
"#dheeraj",
"#dsfdsf",
"#dualworld",
"#errry",
"#george",
"#ggh",
"#gjhggjghj"
]
a.sort(function(a, b) {
var textA = a.toUpperCase();
var textB = b.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
This should work (jsFiddle)
function alphabetical(a, b){
var c = a.toLowerCase();
var d = b.toLowerCase();
if (c < d){
return -1;
}else if (c > d){
return 1;
}else{
return 0;
}
}
yourArray.sort(alphabetical);
To sort an array by a key function applied to an element (toUpperCase here), Schwartzian transform, aka "decorate-sort-undecorate" is your technique of choice:
cmp = function(x, y) { return x > y ? 1 : x < y ? -1 : 0 }
sorted = array.map(function(x) {
return [x.toUpperCase(), x]
}).sort(function(x, y) {
return cmp(x[0], y[0])
}).map(function(x) {
return x[1]
})
The major advantage of this approach is that the key function is called exactly once for each element, which can matter when the key is heavy or has side effects.
I realize that you're looking for a simple answer right now, but this might be something for you to consider learning in the future.

Get the closest color name depending on an hex-color

I try to get the most matching color name depending on an given hex-value. For example if we have the hex-color #f00 we've to get the colorname red.
'#ff0000' => 'red'
'#000000' => 'black'
'#ffff00' => 'yellow'
I use currently the levenshtein-distance algorithm to get the closest color name, works well so far, but sometimes not as expected.
For example:
'#0769ad' => 'chocolate'
'#00aaee' => 'mediumspringgreen'
So any ideas how to get the result closer?
Here's what I made to get the closest color:
Array.closest = (function () {
// http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
function levDist(s, t) {
if (!s.length) return t.length;
if (!t.length) return s.length;
return Math.min(
levDist(s.substring(1), t) + 1,
levDist(t.substring(1), s) + 1,
levDist(s.substring(1), t.substring(1)) + (s[0] !== t[0] ? 1 : 0)
);
}
return function (arr, str) {
// http://stackoverflow.com/q/11919065/1250044#comment16113902_11919065
return arr.sort(function (a, b) {
return levDist(a, str) - levDist(b, str);
});
};
}());
http://jsfiddle.net/ARTsinn/JUZVd/2/
Another thing is the performance! It seems that it there's somewehere a really big issue that makes this really slow (is it the algorithm?).
Levenshtein distance isn't really appropriate here, because it will compare character by character for equality. You need to check each color separately, and you would want 79 to be much closer to 80 than 00.
The following seems to be a lot closer to what you want, with only minimal changes to your code:
Array.closest = (function () {
function dist(s, t) {
if (!s.length || !t.length) return 0;
return dist(s.slice(2), t.slice(2)) +
Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
}
return function (arr, str) {
return arr.sort(function (a, b) {
return dist(a, str) - dist(b, str);
});
};
}());
Note that this will only give reasonable results when both s and t are 6-character color hex codes.
Your code is inefficient because you don't need to sort the entire array to get the closest color. You should instead just loop through the array and keep track of the shortest distance.
For example:
Array.closest = (function () {
function dist(s, t) {
if (!s.length || !t.length) return 0;
return dist(s.slice(2), t.slice(2)) +
Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
}
return function (arr, str) {
var min = 0xffffff;
var best, current, i;
for (i = 0; i < arr.length; i++) {
current = dist(arr[i], str)
if (current < min) {
min = current
best = arr[i];
}
}
return best;
};
}());
Note that after this change Array.closest() will return a single value rather than an array, so you will need to remove the [0] further down in your code.

Fermat's little theorem in JS

I just tried to implement Fermat's little theorem in JavaScript. I tried it both ways, a^(p-1) mod p = 1 and a^p mod p = a mod p.
function fermat(a, p) {
return (((a ^ (p - 1)) % p) === 1);
}
and
function fermat(a, p) {
return ( ( a^p ) % p ) === ( a % p );
}
It doesn't work both ways, is there any way to fix that?
In Javascript ^ means XOR. For exponentiation you need Math.pow(x, y).
function fermat(a, p) {
return Math.pow(a, p - 1) % p === 1;
}
Instead of ^, you need to use Math.pow
In addition to the ^ vs. Math.pow() issue others have pointed out, the next hurdle
you will likely face is the limited precision of the Javascript built-in numeric
types. You will very quickly exceed the range of exactly representable Javascript
numbers once the exponents start getting large, as they will be if you're wanting
to use a routine like this as a primality test. You may want to look into
a Javascript bignum library (for example, this one) that supports exponentiation
and modulus for arbitrarily large integers.
In javascript, the carat (^) is the XOR operator. What you want to use is the Math.pow(x,y) function which is equivalent to x^y.
Here is my code (JavaScript) for checking whether a number is prime based on Fermat Little Theorem.
function getRandomInt(min,max) { /* getting a random between given max and min values */
min = Math.ceil(min);
max = Math.ceil(max);
return Math.floor(Math.random()*(max-min))+min;
}
function getGCD(a,b) { /* getting the greatest common divisor */
var tmp;
while (b !== 0) {
tmp = b;
b = a%b;
a = tmp;
}
return a;
}
function getPower(a,b,p) { /* getting the a^b mod p */
if (b == 1)
return a%p;
else {
x = getPower(a,Math.floor(b/2),p);
if (b%2 == 0)
return (x*x)%p;
else return (((x*x)%p)*a)%p;
}
}
function fermatTesting(Num) { //Checking Num by using Fermat's theorem
var a = getRandomInt(2,Num-1);
if (getGCD(a,Num) !== 1) {
return "COMPOSITE";
}
else {
if (getPower(a,Num-1,Num) !== 1) {
return "COMPOSITE";
}
else {
return "PRIME";
}
}
}
console.log(fermatTesting(57)); //Displays "COMPOSITE"
There's nothing like answering an eleven year old question!
Since it's now 2021 we have support for BigInt, which supports arbitrary precision along with the exponentiation operator (**) and the modulus operator(%).
The function in the accepted answer can be rewritten as
function fermat(a, p) {
return (a**(p-1n) % p) === 1n;
}
where a and p are BigInt values.

Categories