Get range of numbers from the sorted array - javascript

There is a sorted array with numbers, for example:
const array = [100, 400, 700, 1000, 1300, 1600]
There is a function that takes two arguments as input:
function foobar(min, max) {}
The function should return the numbers from the array, starting with the first value that is >= to the min and ending with the last value that is >= to the max.
foobar(250, 1010) // returns [400, 700, 1000, 1300]
foobar(0, 15) // returns [100]
How to implement this using modern JS?
array.filter((num) => {
return num >= min && num <= max
})
Always loses the last number. 🤔

This is a perfect use-case of for...of loop.
const array = [100, 400, 700, 1000, 1300, 1600];
function foobar(array,min,max) {
let new_array = [];
for (let val of array) {
if(min<=val && val<=max) {
new_array.push(val);
} else if(val>max) {
new_array.push(val);
break;
}
}
return new_array;
}
console.log(foobar(array,0,15)); // outputs [100]
console.log(foobar(array,250,1010)); // outputs [400, 700, 1000, 1300]
It's simple, follows conventional programming paradigm and it traverses the array only once.

Here's one way
const array = [100, 400, 700, 1000, 1300, 1600];
const foobar = (min, max) => {
// get the lowest number higher than or equal to max
const lowestHigh = array.find(n => (n >= max));
const within = val => (val >= min && val <= lowestHigh);
return array.filter(within);
};
console.log( foobar(0, 150) );
console.log( foobar(400, 1500) );

Related

Function that takes an input between 0 and 5 and outputs an array of 5 elements that will be used for generating 5 stars in the UI [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm looking for a solution to this problem, I need to put a number between 0 and 5 inclusively and it must output an array of 5 elements,
For example, if I put 5 I must get [100, 100, 100, 100, 100]
Examples:
createStars(3.5) // [100, 100, 100, 50, 0]
createStars(1.6667) // [100, 66.67, 0, 0, 0]
This is my attempt at it
function numberStars(number) {
var array = [];
if (number > 0 && number <= 5) {
for (i = 0; i < 5; i++) {
var multiplied = number * 100;
remainder = multiplied % 100;
array.push(remainder);
multiplied = remainder;
}
}
return array;
}
it gives back [60, 60, 60, 60, 60]
For a JavaScript solution, create an array of size 5 for the output. Then loop through every index. If the given number is larger than the current index, output 100. If the number minus the index is between 0 and 1, then output the decimal part times 100. If none of those conditions are true, then output 0.
function createStars(n) {
const output = Array(5);
for (let i = 0; i < 5; i++) {
let num = n - i;
if (num >= 1) output[i] = 100;
else if (num >= 0) output[i] = num*100;
else output[i] = 0;
}
return output;
}
console.log(createStars(3.5));
console.log(createStars(4.7)); // The only reason that this is [100,100,100,100,70.00000000000001] is because of floating point precision errors
A TypeScript solution would be the exact same, except just with added typedefs.
function createStars(n: number): [number, number, number, number, number] {
const output: [number, number, number, number, number] = [0,0,0,0,0];
for (let i = 0; i < 5; i++) {
let num = n - i;
if (num >= 1) output[i] = 100;
else if (num >= 0) output[i] = num*100;
else output[i] = 0;
}
return output;
}
console.log(createStars(3.5));
console.log(createStars(4.7)); // The only reason that this is [100,100,100,100,70.00000000000001] is because of floating point precision errors
You could multiply the wanted value with 100 and take a minimum value or 100 for mapping and subtract this value from the wanted result.
function createStars(v) {
v *= 100;
return Array.from({ length: 5 }, () => {
const r = Math.min(v, 100);
v -= r;
return r;
})
}
console.log(...createStars(3.5)); // [100, 100, 100, 50, 0]
console.log(...createStars(1.6667)); // [100, 66.67, 0, 0, 0]
And here's a TypeScript solution, which is just the JavaScript solutions with added typedefs.
function createStars(v: number): number[] {
v *= 100;
return Array.from({ length: 5 }, () => {
const r = Math.min(v, 100);
v -= r;
return r;
})
}
console.log(...createStars(3.5)); // [100, 100, 100, 50, 0]
console.log(...createStars(1.6667)); // [100, 66.67, 0, 0, 0]

Alternative to if else chain with range

Please check the code below
if( x > 10 && x <= 100 ){
do.something(1)
}
else if ( x > 100 && x <= 1000 ) {
do.something(2)
}
else if ( x > 1000 && x <= 10000 ) {
do.something(3)
}
else if ( x > 10000 && x <= 100000 ) {
do.something(4)
}
Is the any better alternative to this if/else or switch chain?
Can we make it configurable - so that I can keep all the conditions and corresponding action in one data-structure and write code that can pick all the conditions from that structure and do actions accordingly? This will help me keep all the conditions in a separate conf file and it will be easy to just make the edits to that and not touch the code
NOTE: These ranges may be inconsistent like 100 - 200, 345 - 956, 1000 - 1200
You could take an array and use the shor circuit of Array#some for a found range.
var value = 300;
values = [
[10, () => undefined],
[100, () => do.something(1)],
[1000, () => do.something(2)],
[10000, () => do.something(3),
[100000, () => do.something(4)]
];
values.some(([v, f]) => {
if (value <= v) {
f();
return true;
}
});
This would make it configurable.
const cond = [
{min: 10, max: 100, val: 1},
{min: 100, max: 1000, val: 2},
{min: 1000, max: 10000, val: 3},
{min: 10000, max: 100000, val: 4},
]
do.something(cond.filter(c => x > c['min'] && x < c['max'])[0]['val'])
I think it is fastest way, but not for IE check here
Yes, you can write it for example in .json or .env file, and read it.

Get the index of the first element in an array with value greater than x

I have this array:
var array = [400, 4000, 400, 400, 4000];
How can I get the index of the first element with value greater than 400?
Note: While making sure this question was unique, I came across questions asking this same problem- but for different programming languages.
If there are duplicates of my question that apply to JS, I'd really want to see them.
You can use findIndex here
check this snippet
var array = [400, 4000, 400, 400, 4000];
var index=array.findIndex(function(number) {
return number > 400;
});
console.log(index);
You can use a simple for loop and check each element.
var array = [400, 4000, 400, 400, 4000];
var result;
for(var i=0, l=array.length; i<l; i++){
if(array[i] > 400){
result = i;
break;
}
}
if(typeof result !== 'undefined'){
console.log('number greater than 400 found at array index: ' + result);
} else {
console.log('no number greater than 400 found in the given arrry.');
}
Read up: for - JavaScript | MDN
var array = [0, 0, 3, 5, 6];
var x = 5;
var i = 0;
while (array[i] <= x) {
i++;
}
let array = [0, 0, 3, 5, 6];
let x = 5;
let i = 0;
for (; i<array.length && array[i] <= x; i++);
If there is an element greater than x, this returns the index of the first one. Otherwise it returns the length of the array.

How can I find all indexes of the max value of an array in javascript?

I am trying to find a way to get the max value of an array, then find all indexes of that value. I want to repeat this two more times.
I have an array of 8 scores. I want to find all first places, all second places, and all third places.
Array = [0, 400, 300, 400, 300, 200, 100, 200]
1st place indexes: 1, 3
2nd place indexes: 2, 4
3rd place indexes: 5, 7
How can I achieve this in javascript?
The following code does the trick:
var scores = [0, 400, 300, 400, 300, 200, 100, 200];
// make a working copy, so that we can change the working copy
// while doing the calculations without changing the original array
var working = scores.slice(0),
max,
indices,
numberOfPlaces = 3,
results = [];
for (var p = 0; p < numberOfPlaces; p++) {
max = Math.max.apply(null, working);
indices = [];
for (var i = 0; i < working.length; i++)
if (working[i] === max && working[i] > Number.NEGATIVE_INFINITY) {
indices.push(i);
working[i] = Number.NEGATIVE_INFINITY;
}
results.push(indices);
}
For your input results will be [[1,3], [2,4], [5,7]]. That is, results[0] will hold the first place indices, results[1] will hold the second place indices, and so on.
If you later decided you only wanted the first two places, or your wanted the first five, just change the numberOfPlaces variable.
Assuming the scores are not big numbers, you can build a hash of "score to indexes", and then sort by keys, and print out the indexes:
the running sample:
http://jsfiddle.net/nmA35/2/
the code:
var arr = [0, 400, 300, 400, 300, 200, 100, 200];
var hashValueToPosition = {};
var i;
for (i = 0; i < arr.length; i++) {
hashValueToPosition[arr[i]] = (hashValueToPosition[arr[i]] || []);
hashValueToPosition[arr[i]].push(i);
}
// see http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object for Object.keys or the following:
var getKeys = function(obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
var arrMaxToMinScores = getKeys(hashValueToPosition).sort().reverse();
for (i = 0; i < arrMaxToMinScores.length; i++) {
$("body").append("<pre>" + arrMaxToMinScores[i] + ": " + JSON.stringify(hashValueToPosition[arrMaxToMinScores[i]]) + "</pre>");
}
function awardPrizes(arr){
var L= arr.length, prizes= [[], [], []], n;
// save the three highest scores in scores array:
// eg: [400,300,200]
var scores= arr.slice().filter(function(n, i){
return arr.indexOf(n)== i;
}).sort(function(a, b){ return b-a}).slice(0, 3);
//put the high scoring indexes in the relevant prizes array:
arr.forEach(function(itm, i){
n= scores.indexOf(itm);
if(n!= -1) prizes[n].push(i);
});
return prizes;
//[first group,second group,third group]
}
var data= awardPrizes([0, 400, 300, 400, 300, 200, 100, 200]);
/* returned value: (Array)
[
[1, 3],
[2, 4],
[5, 7]
]
*/
Like functional programming?
a={};[0, 400, 300, 400, 300, 200, 100, 200].forEach(
(el,i) => a[el]? a[el].push(i) : a[el]=[i]
);
Object.keys(a).sort().reverse().map(k => [Number(k),a[k].sort()])
Basically hashes all the values, then goes through the keys in descending order, mentioning the indexes in ascending order. Ex:
[
[400,[1,3]],
[300,[2,4]],
[200,[5,7]],
[100,[6]],
[0,[0]]
]

Digit value to array in JavaScript

I have number 8939, then I want to get the array [8000,7000,6000,5000,4000,3000,2000,1000] and example if I have 340 then I can get the array 300,200,100.
I just knew that , if I user
i = i/1000 * 1000
Then I can round down 8939 to 8000, but I don't know how can I got the result that I want above.
No reason to complicate it, you can use a for loop
function getArrForNum(num){
var arr = []; // create a new array
var digitNum = num.toString().length; //get the number of digits, can use Math.log instead
var mulOf10 = Math.pow(10,digitNum-1);
for(var i=1;i*mulOf10 < num;i++){
arr.push(i*mulOf10); // push the next multiple of 1000
}
return arr; //return it
}
Then you can use it:
getArrForNum(3211); //1000,2000,3000
getArrForNum(321); //100,200,300
Here is a one line version just for the challenge, but I strongly suggest avoiding it :)
Array(+(832+"")[0]).join(".").split(".").map(function(_,i){ return (i+1)*Math.pow(10,(832+"").length-1);}); // 800,700,600,500,400,300,200,100
Array(+(3332+"")[0]).join(".").split(".").map(function(_,i){ return (i+1)*Math.pow(10,(3332+"").length-1);}); //1000,2000,3000
The following will do what you require:
function getArray(value) {
var valueOrder = Math.floor( Math.log(value) / Math.log(10) );
var result = [];
var step = Math.pow (10, valueOrder);
var currentValue = step;
while (currentValue < value) {
result.push (currentValue);
currentValue += step;
}
return result.reverse();
}
Demonstration here: http://jsfiddle.net/5zXc5/
getArray(8939) => 8000,7000,6000,5000,4000,3000,2000,1000
getArray(340) => 300,200,100
You haven't mentioned edge cases (e.g. 1000), but those can be handled easily enough by altering the < to a <= in the while, or adjusting the call to Math.floor.
function f(a) {
var len = a.toString().length,
m = Math.pow(10, len - 1),
e = a.toString().charAt(0),
num = e * m,
i = 1
out = [];
for (i = 0; i < e; i++) {
out.push(num - i * m);
}
return out;
}
f(8939); // [8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000]
f(340); // [300, 200, 100]
f(0); // []
f(10); // [10]
f(20); // [20, 10]
f(70); // [70, 60, 50, 40, 30, 20, 10]
function g(n){
var p = Math.floor(Math.log(n)/Math.log(10)), // n.toString().length - 1 is cool (in others' answers).
m = Math.pow(10,p),
d = Math.floor(n/m),
r = [];
for(; d>0; d--){
r.push(d*m);
}
return r;
}
g(8939); // [8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000]
function mine(num){
var result =[];
var count = 0;
var i = num;
var f;
while(i!=0){
i = Math.floor(i/10);
count++;
}
f = Math.floor(num/Math.pow(10,count-1));
for(i =f;i>=1 && count>1;i--){
result.push(i*Math.pow(10,count-1));
}
return result;
}
mine(8939); // [8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000]
mine(340); // [300, 200, 100]
mine(0); // []
mine(10); // [10]
mine(20); // [20, 10]
mine(70); // [70, 60, 50, 40, 30, 20, 10]

Categories