Related
I am trying to get 5 closest elements to given element, including that element, in array. For example, if we have:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17]
and I want to get 5 closest elements to 11, it should return [4, 7, 11, 12, 13]. If i pass 1 it should return [1, 2, 3, 4, 7]. If I pass 15 it should return [11, 12, 13, 15, 17].
I'm not sure what you meant;
You might've meant a code to find the element and return the five nearest elements to it by place in the array;
Or you might've meant a code to find the 5 numbers closest to a number you say.
IF you meant the first case
There are two ways to do so,
A value as a parameter
Use this code:
function closestNByValue(arr, value, n) {
let ind = arr.indexOf(value);
let finalArr = [];
if (n > arr.length) {
finalArr = Array.from(arr);
} else if (ind == -1) {
finalArr = [];
} else if (ind <= n/2 - 0.5) {
finalArr = arr.slice(0, n);
} else if (ind >= (arr.length - n/2) - 0.5) {
finalArr = arr.slice(-n);
} else if (n%2 == 0) {
finalArr = arr.slice(ind-(n/2), ind+(n/2));
} else {
finalArr = arr.slice(ind-(n/2 - 0.5), ind+(n/2 + 0.5));
}
return finalArr;
}
console.log(closestNByValue([1, 2, 3, 4, 7, 11, 12, 13, 15, 17], 11, 5))
How does it do the job?
Okay first we need to find the index of the value and save it in ind (short form of 'index') and we check multiple different situations for what the ind is so we'd be able to output the best answer as finalArr.
There are two exceptions; what if there was no such value in our array? then ind = -1 and we'd return an empty array; or what if the number of elements nearby that we seek is larger than or equal to the arr.length? then we'd return all of the arr.
But if there were no exceptions, there are three different situations for the ind; first, ind is a number that makes us have all of the finalArr values from the first of arr, second, ind be a number that makes us have all of the finalArr values from the last of arr, and third, ind being a number that we have to select half from the indexes smaller than ind and half, larger.
If it is the third way, the way we select we'd be different depending on the oddity of the numbers we want to select.
And we'll have a conditional statement for each situation and return the finalArr.
An index as a parameter
function closestNByIndex(arr, ind, n) {
let finalArr = [];
if (n > arr.length) {
finalArr = Array.from(arr);
} else if (ind == -1) {
finalArr = [];
} else if (ind <= n/2 - 0.5) {
finalArr = arr.slice(0, n);
} else if (ind >= (arr.length - n/2) - 0.5) {
finalArr = arr.slice(-n);
} else if (n%2 == 0) {
finalArr = arr.slice(ind-(n/2), ind+(n/2));
} else {
finalArr = arr.slice(ind-(n/2 - 0.5), ind+(n/2 + 0.5));
}
return finalArr;
}
console.log(closestNByIndex([1, 2, 3, 4, 7, 11, 12, 13, 15, 17], 5, 5))
Similar to the first code it works, though we have the index and we don't search for it.
The point is, if you use the function with value, it'd do the nearest 5 elements of the first value that equals the entry but such confusion is not being tolerated in the second code.
IF you meant the second case
This is a code I coded:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17];
function allDiff(arr, num1, num2) {
const finalArr = [];
const x = Math.abs(num2 - num1);
for (let y = 0; y < arr.length; y++) {
if (Math.abs(arr[y] - num1) == x) {
finalArr.push(arr[y]);
}
}
return finalArr;
}
function deleteArr(arr, delet) {
for (let x = 0; x < arr.length; x++) {
if (delet.includes(arr[x])) {
delete arr[x];
}
}
return arr;
}
function closest(arr, num) {
const map = new Map()
arr2 = Array.from(arr);
let key, value;
for (let x = 0; x < arr2.length; x++) {
key = Math.abs(arr2[x] - num);
value = allDiff(arr2, num, arr2[x]);
arr2 = deleteArr(arr2, value);
map.set(key, value);
}
return map;
}
function closestN(arr, num, n) {
const map = closest(arr, num);
const mapKeys = Array.from(map.keys());
const mapKeysSorted = mapKeys.sort(function(a, b) {
return a - b
});
let finalArr = [];
let y;
for (let i = 0; i < mapKeysSorted.length; i++) {
if (n <= 0) {
break;
}
y = map.get(mapKeysSorted[i]);
if (n < y.length) {
finalArr = finalArr.concat(y.slice(0, n + 1));
break;
}
finalArr = finalArr.concat(y);
n -= y.length;
}
return finalArr;
}
console.log(closestN(arr, 11, 5));
It might be a little too long, but I have programmed it as you can give it any array (arr) with integer values, an integer (num) that you'd like it to be the base and another integer (n) for the number of the size of the output array, 5 in this case.
Explaining the code
The function closest would return a map of (the difference between the numbers, a list of the numbers in the arr that differs the number equal to their key).
The main function, closestN, calls the closest function and saves the map in the map variable.
Then it sorts the keys of the map in mapKeysSorted.
Now, a for loop loops through the mapKeySorted array and pushes new elements to the finalArr until the size of the finalArr reaches the number of elements we seek.
The main function is the closestN.
Here's a way to get to your goal:
To start, first thing to do is finding the index of the wanted number in the array. Example index of 1 in your array arr is 0. The index will help in extracting the numbers later on. The method findIndex will help us in finding the index.
Then, we need to find the position at which will start extaracting the closest numbers (in terms of position not value). As seen from the desired output you have provided, usually you want the returned array to be in the following structure:
output: [
2 nearest numbers (from N left),
the wanted number,
2 nearest numbers (from N right)
]
This can get tricky so we should make sure to deal with some edge case like when the wanted element is sitting at position 0.
Extract the numbers and return them as an array as described by your desired output. The use of slice method will come in handy here which allow us to extract the numbers just as we need.
Here's a live demo demonstrating solution:
const arr = [1, 2, 3, 4, 7, 11, 12, 13, 15, 17],
/** a function that returns an array containing the "5" (depending on "arr" length that could be less) nearest numbers (in terms of position) in "arr" array to the supplied number "n" */
findClosestNumbers = n => {
/** make sure we don't exceed the array length */
const toTake = 5 > arr.length ? arr.length : 5,
/** find the index of the wanted nulber "n", if "-1" is returned then "n" cannot be found ion the array "arr" */
idx = arr.findIndex(el => n == el),
/**
* from where we should start returning the nearest numbers (the position of the first number to extract from "arr"
* the below condition help deal with some edge cases like when "n" is the last element in "arr"
*/
startIdx = idx + toTake / 2 > arr.length ?
arr.length - 5 :
(idx - 2 >= 0 ?
idx - 2 :
0);
/** return the nearest numbers or return an empty array "[]" if the number "n" is not found on the array "arr" */
return idx == -1 ? [] : arr.slice(startIdx, startIdx + 5);
};
/** run for various scenarios */
console.log('For 1 =>', findClosestNumbers(1));
console.log('For 11 =>', findClosestNumbers(11));
console.log('For 15 =>', findClosestNumbers(15));
console.log('For 17 =>', findClosestNumbers(17));
.as-console-wrapper {
max-height: 100%!important;
}
The demo above is meant to help you understand how things could work and it is not the only way to get to your goal. Also, because I kept it as simple as possible, the above demo is wide open for improvements.
I am being stuck in situation where the problem is defined as:
Harshad/Niven numbers are positive numbers that are divisible by the sum of their digits. All single-digit numbers are Harshad numbers.
For example, 27 is a Harshad number as 2 + 7 = 9, and 9 is a divisor
of 27.
Harshad numbers can occur in consecutive clusters. The numbers 1
through 10 are Harshad numbers. The numbers 132 and 133 are both
Harshad numbers. The numbers 1014, 1015, 1016, 1017 are Harshad
numbers.
Create a function that takes a number and returns an array of two
elements. The first element is the length of the Harshad cluster of
which the number is a part. The second is its order in the cluster.
Examples harshad(5) ➞ [10, 5] // cluster = [1, 2, 3, 4, 5, 6, 7, 8, 9,
10] // The second element should be the layman order in the //
cluster, not the programming index.
harshad(133) ➞ [2, 2] // cluster = [132, 133]
so i have figured out a way to find out all the harshed cluster greater than the number passed as arguement to function whose code is defined below
function track(num) {
let a = num.toString().split("");
let b = a.reduce((a, b) => +a + +b, 0);
if (num % b != 0) {return;}
console.log(num,num%b);
if (num % b == 0) {
num++;
track(num);
}
}
track(1015);
so console.log() gives me 1015,1016 and 1017
cluster as they are greater than 1015 which is passed to the function now how can i check for the numbers smaller than 1015 as 1014 should also be the answer but i just cant write another IF statement after the first IF statement and make it as
function track(num) {
let a = num.toString().split("");
let b = a.reduce((a, b) => +a + +b, 0);
if (num % b != 0) {return;}
console.log(num,num%b);
if (num % b == 0) {
num++;
track(num);
}
if(num%b==0){
num--
track(num)
}
}
track(1015);
as this makes no sense
You could separate the functions, one for checking if a number is a harshad value and another which collects these numbers by decrementing the value and incrementing and collecting valid numbers in an array.
function harshad(value) {
function isHarshad(value) {
return value % Array.from(value.toString(), Number).reduce((a, b) => a + b) === 0;
}
var cluster = [],
left = value,
right = value + 1;
while (isHarshad(left)) cluster.unshift(left--);
while (isHarshad(right)) cluster.push(right++);
return [cluster.length, cluster.indexOf(value) + 1];
}
console.log(harshad(5)); // [10, 5] cluster = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(harshad(133)); // [ 2, 2] cluster = [132, 133]
console.log(harshad(1015)); // [ 4, 2] cluster = [1014, 1015, 1016, 1017]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Try this:
function track(num) {
const isHarshed = n => {
let a = n.toString().split("").reduce((a, b) => (+a) + (+b), 0);
return n % a === 0;
};
if (!isHarshed(num)) {return false;}
let index = 1;
let count = 1;
let n = num - 1;
while(isHarshed(n)) {
count++;
index++;
n--;
}
n = num + 1;
while(isHarshed(n)) {
count++;
n++;
}
return [count, index];
}
console.log(track(5));
console.log(track(133));
I have the following graph, which is a representation of an array [2,8,12,5,3,...]. X axis is in seconds. I want to break this array into multiple parts when y values stays 0 for longer than 2 seconds. So the array in this example would break into 3 parts: x = 0 to 8, x = 8 to 13 and x = 13 to 20 because y stays = 0 for more than 2 seconds from 8 to 13. In practice this array could be huge. What would be fastest method to do this in pure javascript (or if needed lodash/underscore)? Currently I am looping through this array to mark 2 second stop times. Is there a better way of doing this?
You could use an iterative approach with one loop while checking the expected zero value and decide if the threshold is reached or not. of not, then delete the last interval and append the length to the array before.
This proposal yields
with threshold = 2:
[
[ 1, 7],
[ 8, 13],
[14, 20]
]
with threshold = 7:
[
[ 1, 20]
]
var y = [2, 8, 12, 5, 3, 2, 0, 0, 3, 4, 8, 10, 8, 10],
x = [1, 2, 4, 5, 6, 7, 8, 13, 14, 15, 16, 18, 19, 20],
threshold = 2,
isZero = false;
result = [];
y.forEach(function (a, i) {
var last = result[result.length - 1];
if ((a === 0) !== isZero) {
if (last) {
last[1] = x[i];
}
return;
}
isZero = !isZero;
if (last && isZero && x[i] - last[0] < threshold) {
result.pop();
if (result[result.length - 1]) {
result[result.length - 1][1] = x[i];
}
return;
}
result.push([x[i]]);
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You'll always need to look at the values of the array, so you won't be able to get further than an O(n) solution. The most efficient would probably be to run through the array with a variable containing the amount of zeros you've passed through at a certain point.
The function below is a hastily made implementation of this. I've also used a variable to store the previous index. This could also be calculated from the split array, but that would be rather inefficient if you're really talking about huge arrays.
function splitArray(array, treshold) {
var zeros = 0,
previousIdx = 0,
splitArrays = [];
array.forEach(function(point, idx) {
if (point === 0) {
zeros++;
if (zeros == treshold && previousIdx != idx - treshold + 1) {
splitArrays.push(array.slice(previousIdx, idx - treshold + 1));
previousIdx = idx - treshold + 1;
}
} else if (zeros >= treshold) {
splitArrays.push(array.slice(previousIdx, idx));
previousIdx = idx;
zeros = 0;
}
});
if (previousIdx != array.length -1) {
splitArrays.push(array.slice(previousIdx));
}
return splitArrays;
}
I've created a JSFiddle that shows this function in action with some test data: https://jsfiddle.net/Glodenox/La8m3du4/2/
I don't doubt this code can still be improved though.
If you just want to get the indices of the sections instead of an array with all data in separate arrays, you can replace the three array.slice(a, b) statements with [a, b-1].
I am working on the following problem:
Given an arrayOfInts, find the highestProduct you can get from k of the integers.
This is the solution I have come up with so far based on a generalization of getting the highestProduct from 3 of the integers.
var getHighestProductOfk = function (arrayOfInts, k) {
if (arrayOfInts.length < k) {
throw Error('Array should be higher than k');
}
highestProductArray = [arrayOfInts[0]];
lowestProductArray = [arrayOfInts[0]];
for (let i=1; i<k; i++) {
highestProductArray[i] = highestProductArray[i-1]*arrayOfInts[i];
lowestProductArray[i] = lowestProductArray[i-1]*arrayOfInts[i];
}
for(let i=1; i<arrayOfInts; i++) {
let currentInt = arrayOfInts[i];
for(let j=k-1; j>=0; j--) {
highestProductArray[j] = Math.max(
highestProductArray[j],
highestProductArray[j-1]*currentInt,
lowestProductArray[j-1]*currentInt
);
lowestProductArray[j] = Math.min(
lowestProductArray[j],
lowestProductArray[j-1]*currentInt,
highestProductArray[j-1]*currentInt
);
}
// highest number
highestProductArray[0] = Math.max(highestProductArray[0], currentInt)
// lowest number
lowestProductArray[0] = Math.max(lowestProductArray[0], currentInt)
}
return highestProductArray[k-1];
}
Any idea what I do wrong?
for the following example [1, 10, -5, 1, -100], the result is -50 instead of 5000.
lowest number is 1 and the highest is 1 instead of -100 and 10
The solution for the highestProduct of three of the integers:
var getHighestProductOfThree = function (arrayOfInts) {
if (arrayOfInts.length < 3) {
throw Error('Array should be higher than 3');
}
let highestProductOfThree = arrayOfInts[0]*arrayOfInts[1]*arrayOfInts[2];
let highestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];
let lowestProductOfTwo = arrayOfInts[0]*arrayOfInts[1];
let highest = arrayOfInts[0];
let lowest = arrayOfInts[0];
for (let i=1; i<arrayOfInts.length; i++) {
let currentInt = arrayOfInts[i];
highestProductOfThree = Math.max(
highestProductOfThree,
highestProductOfTwo*currentInt,
lowestProductOfTwo*currentInt
);
highestProductOfTwo = Math.max(
highestProductOfTwo,
currentInt*highest,
currentInt*lowest
);
lowestProductOfTwo = Math.min(
lowestProductOfTwo,
currentInt*lowest,
currentInt*highest
);
highest = Math.max(
highest,
currentInt
);
lowest = Math.min(
lowest,
currentInt
);
}
return highestProductOfThree;
}
Here's an idea. Sort the numbers. Next, pick from the largest positive numbers as many as you can, up to k of them. Now pick the largest even group from the smallest negative numbers that form a larger product than the smallest positive numbers, which we will replace with them. (There are some edge cases, such as only one negative and k - 1 positives).
Pick 3 from [1, 10, -5, 1, -100]
Sort => [-100,-5,1,1,10]
Pick largest positives => 10 * 1 * 1
Pick largest even number of smallest negatives we can,
whose product is greater than the one replaced
=> (-100) * (-5) > 1 * 1
Answer => 10 * (-100) * (-5)
Based on my preliminary thoughts, I suggest to sort the values ascending, take the highest value, if the count is odd and use the rest with pairs.
This keeps a positive product with a loop until all needed factors are used.
In a while loop with a check for count, the pairs are chosen, if the product is greate than of the beginning of the array. This includes negative numbers, but works for only positive or negative numbers as well.
function getHighestProductOfK(a, k) {
var p = 1;
a.sort(function (a, b) { return a - b; });
if (k > a.length || k & 2 && a[a.length - 1] < 0) {
return;
}
if (k % 2) {
p = a.pop();
k--;
}
while (k) {
p *= a[0] * a[1] > a[a.length - 2] * a[a.length - 1] ? a.shift() * a.shift() : a.pop() * a.pop();
k -= 2;
}
return p;
}
console.log(getHighestProductOfK([1, 10, -5, 1, -100], 3));
console.log(getHighestProductOfK([3, 4, 5, 6, 7], 3));
console.log(getHighestProductOfK([-3, -4, -5, -6, -7], 3));
console.log(getHighestProductOfK([3, 4, -5, -6, -7], 3));
Needs some testing to make sure it always gives good answers..
function largestProduct(k, arr) {
if (k > arr.length) throw new RangeError('Not enough numbers');
let pos = [],
neg = [];
arr.forEach(e => {
if (e >= 0) pos.push(e);
else neg.push(e);
});
pos.sort((a, b) => a < b); // 9, 8, 7, ...
neg.sort((a, b) => a > b); // -9, -8, -7, ...
if (pos.length === 0 && k % 2) // k requires odd number of negatives
return neg.slice(-k); // give the smallest number TODO: same return
let big = [];
while (k > 1) grow();
if (k === 1) { // we've reached the end of doubles but still need more
if (pos.length) big.push(pos[0]);
else { // ran out of positives, backtrack
big = big.slice(0, -1);
big.push(neg[0], neg[1]);
}
}
return {
factors: big,
product: big.reduce((a, b) => a * b, 1)
};
function grow() { // choose the next best number
let doublepos = pos[0] * pos[1],
doubleneg = neg[0] * neg[1];
if (doublepos > doubleneg || doubleneg !== doubleneg) {
big.push(pos[0]);
pos = pos.slice(1);
k -= 1;
} else {
big.push(neg[0], neg[1]);
neg = neg.slice(2);
k -= 2;
}
}
}
Say I have the following checkbox:
<input type="checkbox" value="1-25" />
To get the two numbers that define the boundaries of range I'm looking for, I use the following jQuery:
var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);
How do I then create an array that contains all integers between lowEnd and highEnd, including lowEnd and highEnd themselves? For this specific example, obviously, the resulting array would be:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
list.push(i);
}
ES6 :
Use Array.from (docs here):
console.log(
Array.from({length:5},(v,k)=>k+1)
)
In JavaScript ES6:
function range(start, end) {
return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
var result = range(9, 18); // [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
console.log(result);
For completeness, here it is with an optional step parameter.
function range(start, end, step = 1) {
const len = Math.floor((end - start) / step) + 1
return Array(len).fill().map((_, idx) => start + (idx * step))
}
var result = range(9, 18, 0.83);
console.log(result);
I would use range-inclusive from npm in an actual project. It even supports backwards steps, so that's cool.
I highly recommend underscore or lo-dash libraries:
http://underscorejs.org/#range
(Almost completely compatible, apparently lodash runs quicker but underscore has better doco IMHO)
_.range([start], stop, [step])
Both libraries have bunch of very useful utilities.
My version of the loop ;)
var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
arr.push(lowEnd++);
}
fastest way
while-- is faster on most browsers
direct setting a variable is faster than push
function:
var x=function(a,b,c,d){d=[];c=b-a+1;while(c--){d[c]=b--}return d},
theArray=x(lowEnd,highEnd);
or
var arr=[],c=highEnd-lowEnd+1;
while(c--){arr[c]=highEnd--}
EDIT
readable version
var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
arr[c] = highEnd--
}
Demo
http://jsfiddle.net/W3CUn/
FOR THE DOWNVOTERS
performance
http://jsperf.com/for-push-while-set/2
faster in ie and 3x faster in firefox
only on aipad air the for loop is a little faster.
tested on win8, osx10.8, ubuntu14.04, ipad, ipad air, ipod;
with chrome,ff,ie,safari,mobile safari.
i would like to see the performance on older ie browsers where the for loop isn't that optimized!
function range(j, k) {
return Array
.apply(null, Array((k - j) + 1))
.map(function(_, n){ return n + j; });
}
this is roughly equivalent to
function range(j, k) {
var targetLength = (k - j) + 1;
var a = Array(targetLength);
var b = Array.apply(null, a);
var c = b.map(function(_, n){ return n + j; });
return c;
}
breaking it down:
var targetLength = (k - j) + 1;
var a = Array(targetLength);
this creates a sparse matrix of the correct nominal length. Now the problem with a sparse matrix is that although it has the correct nominal length, it has no actual elements, so, for
j = 7, k = 13
console.log(a);
gives us
Array [ <7 empty slots> ]
Then
var b = Array.apply(null, a);
passes the sparse matrix as an argument list to the Array constructor, which produces a dense matrix of (actual) length targetLength, where all elements have undefined value. The first argument is the 'this' value for the the array constructor function execution context, and plays no role here, and so is null.
So now,
console.log(b);
yields
Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]
finally
var c = b.map(function(_, n){ return n + j; });
makes use of the fact that the Array.map function passes: 1. the value of the current element and 2. the index of the current element, to the map delegate/callback. The first argument is discarded, while the second can then be used to set the correct sequence value, after adjusting for the start offset.
So then
console.log(c);
yields
Array [ 7, 8, 9, 10, 11, 12, 13 ]
My five cents:
Both direction array of integers function.
When range(0, 5) become [0, 1, 2, 3, 4, 5].
And range(5, 0) become [5, 4, 3, 2, 1, 0].
Based on this answer.
function range(start, end) {
const isReverse = (start > end);
const targetLength = isReverse ? (start - end) + 1 : (end - start ) + 1;
const arr = new Array(targetLength);
const b = Array.apply(null, arr);
const result = b.map((discard, n) => {
return (isReverse) ? n + end : n + start;
});
return (isReverse) ? result.reverse() : result;
}
P.S. For use in real life you should also check args for isFinite() and isNaN().
function createNumberArray(lowEnd, highEnd) {
var start = lowEnd;
var array = [start];
while (start < highEnd) {
array.push(start);
start++;
}
}
If the start is always less than the end, we can do:
function range(start, end) {
var myArray = [];
for (var i = start; i <= end; i += 1) {
myArray.push(i);
}
return myArray;
};
console.log(range(4, 12)); // → [4, 5, 6, 7, 8, 9, 10, 11, 12]
If we want to be able to take a third argument to be able to modify the step used to build the array, and to make it work even though the start is greater than the end:
function otherRange(start, end, step) {
otherArray = [];
if (step == undefined) {
step = 1;
};
if (step > 0) {
for (var i = start; i <= end; i += step) {
otherArray.push(i);
}
} else {
for (var i = start; i >= end; i += step) {
otherArray.push(i);
}
};
return otherArray;
};
console.log(otherRange(10, 0, -2)); // → [10, 8, 6, 4, 2, 0]
console.log(otherRange(10, 15)); // → [10, 11, 12, 13, 14, 15]
console.log(otherRange(10, 20, 2)); // → [10, 12, 14, 16, 18, 20]
This way the function accepts positive and negative steps and if no step is given, it defaults to 1.
Solution with pure ES6
Inspired by m59's answer above, but without the dependency on fill:
const range = (start, stop) => Array.from({ length: stop - start + 1 }, (_, i) => start + i)
So you can use it like:
range(3,5)
=> [3, 4, 5]
var values = $(this).val().split('-'),
i = +values[0],
l = +values[1],
range = [];
while (i < l) {
range[range.length] = i;
i += 1;
}
range[range.length] = l;
There's probably a DRYer way to do the loop, but that's the basic idea.
You can design a range method that increments a 'from' number by a desired amount until it reaches a 'to' number.
This example will 'count' up or down, depending on whether from is larger or smaller than to.
Array.range= function(from, to, step){
if(typeof from== 'number'){
var A= [from];
step= typeof step== 'number'? Math.abs(step):1;
if(from> to){
while((from -= step)>= to) A.push(from);
}
else{
while((from += step)<= to) A.push(from);
}
return A;
}
}
If you ever want to step by a decimal amount : Array.range(0,1,.01)
you will need to truncate the values of any floating point imprecision.
Otherwise you will return numbers like
0.060000000000000005 instead of .06.
This adds a little overhead to the other version, but works correctly for integer or decimal steps.
Array.range= function(from, to, step, prec){
if(typeof from== 'number'){
var A= [from];
step= typeof step== 'number'? Math.abs(step):1;
if(!prec){
prec= (from+step)%1? String((from+step)%1).length+1:0;
}
if(from> to){
while(+(from -= step).toFixed(prec)>= to) A.push(+from.toFixed(prec));
}
else{
while(+(from += step).toFixed(prec)<= to) A.push(+from.toFixed(prec));
}
return A;
}
}
Adding http://minifiedjs.com/ to the list of answers :)
Code is similar to underscore and others:
var l123 = _.range(1, 4); // same as _(1, 2, 3)
var l0123 = _.range(3); // same as _(0, 1, 2)
var neg123 = _.range(-3, 0); // same as _(-3, -2, -1)
var empty = _.range(2,1); // same as _()
Docs here:
http://minifiedjs.com/api/range.html
I use minified.js because it solves all my problems with low footprint and easy to understand syntax. For me, it is a replacement for jQuery, MustacheJS and Underscore/SugarJS in one framework.
Of course, it is not that popular as underscore. This might be a concern for some.
Minified was made available by Tim Jansen using the CC-0 (public domain) license.
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
_Array = (length) => Object.keys(Array.from({length}))
//_Array = [0, 1, 2, 3, 4]
const range = (start: number, end: number) => {
for (var i = start, list = []; i <= end; list.push(i), i++);
return list;
};
Hope the below method will help someone.
Here count variable can be used to mention the array length.
const generateRandomArryOfNumbers = (min = 1, max = 100, count = 31) => {
return Array.from(new Array(count), () =>
Math.floor(Math.random() * (max - min + 1) + min)
);
};
Here's 3 functions that should cover everything I could think of (including fixes for problems in some other answers): rangeInt(), range(), and between(). Both ascending and descending orders are accounted for in all cases.
Examples
rangeInt()
Includes endpoints and only deals with integers
rangeInt(1, 4) // [1, 2, 3, 4] Ascending order
rangeInt(5, 2) // [5, 4, 3, 2] Descending order
rangeInt(4, 4) // [4] Singleton set (i.e. not [4, 4])
rangeInt(-1, 1) // [-1, 0, 1] Mixing positive and negative
range()
Same as rangeInt() except
Not limited to integers
Allows for a specified number of points in a third parameter
range(0, 10, 2) // [0, 3.333, 6.666, 10] Gets endpoints and 2 points between
range(0, 1.5, 1) // [0, 0.75, 1.5] Accepts fractions
between()
Same as range() except
Endpoints are excluded
There are no singleton sets (an empty array will be returned instead)
between(0, 10, 2) // [3.333, 6.666]
between(-1, -1.5) // [-1.25]
between(4, 4, 99) // []
Source
/**
* Gets a set of integers that are evenly distributed along a closed interval
* #param {int} begin - Beginning endpoint (inclusive)
* #param {int} end - Ending endpoint (inclusive)
* #return {Array} Range of integers
*/
function rangeInt( begin, end ) {
if ( !Number.isInteger(begin) || !Number.isInteger(end) ) {
throw new Error('All arguments must be integers')
}
return range(begin, end, Math.abs(end - begin) - 1)
}
/**
* Gets a set of numbers that are evenly distributed along a closed interval
* #param {Number} begin - Beginning endpoint (inclusive)
* #param {Number} end - Ending endpoint (inclusive)
* #param {int} points - How many numbers to retrieve from the open interval
* #return {Array} Range of numbers
*/
function range( begin, end, points ) {
if ( begin !== end ) {
return [ begin, ...between(begin, end, points), end ]
}
else if ( Number.isFinite(begin) ) {
return [ begin ] // singleton set
}
else throw new Error('Endpoints must be finite')
}
/**
* Gets a subset of numbers that are evenly distributed along an open interval
* #param {Number} begin - Beginning endpoint (exclusive)
* #param {Number} end - Ending endpoint (exclusive)
* #param {int} points - How many numbers to retrieve from the interval
* #return {Array} Retrieved numbers
*/
function between( begin, end, points = 1 ) {
if ( !Number.isFinite(begin) || !Number.isFinite(end) || !Number.isFinite(points) ) {
throw new Error('All arguments must be finite')
}
const set = []
// Skip if an open interval does not exist
if ( begin !== end ) {
const step = (end - begin) / (points + 1)
for ( let i = 0; i < points; i++ ) {
set[i] = begin + (i + 1) * step
}
}
return set
}
Solving in underscore
data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );
function getRange(a,b)
{
ar = new Array();
var y = a - b > 0 ? a - b : b - a;
for (i=1;i<y;i++)
{
ar.push(i+b);
}
return ar;
}