How to use IndexOf for a range of values - javascript

var Myarray = [0,4,6,14,50]
var Index = Myarray.indexOf(40-50)
How do I write this in p5, where it returns the index of all the numbers inside a specific range?
Mistakes I could have made
I may be using indexOf, which is the wrong command
I may not know the full extent of how indexOf works
If there isn't a command, is it possible to use a for loop
Note: The 40-50 isn't meant to be from any specific language, it's just to show what I'm going for.

You could get the indices and filter with the wanted range.
const
array = [0, 4, 6, 14, 50],
indices = [...array.keys()].filter(i => array[i] >= 40 && array[i] <= 50);
console.log(indices);

You can use Array.prototype.map() and Array.prototype.filter().
const numbers = [0, 4, 6, 14, 50],
solution = numbers.map((num, i) => num >= 40 && num <= 50 ? i : -1).filter(val => val !== -1);
console.log(solution);
.

Try something like this:
var Myarray = [0, 4, 6, 14, 50]
function getElementsInRange(array, min, max) {
return array.filter(i => (i - min) * (i - max) <= 0)
}
console.log(getElementsInRange(Myarray, 14, 50))
Updated thanks to #Nina Scholz.

As I understand the problem below might be the solution to get the indices of items in range.
function indicesOfIntegerRange(numbersArray, num1, num2) {
if (!numbersArray || !numbersArray.length) {
return [-1];
}
if (!num1) {
return [numbersArray.indexOf(num2)];
}
if (!num2) {
return [numbersArray.indexOf(num1)];
}
const min = Math.min(num1, num2);
const max = Math.max(num1, num2);
return numbersArray
.filter((n) => n >= min && n <= max)
.map((n) => numbersArray.indexOf(n));
}
Usage:
const numbersArray = [0, 4, 6, 14, 50];
console.log(indicesOfIntegerRange()); // [-1]
console.log(indicesOfIntegerRange([])); // [-1]
console.log(indicesOfIntegerRange(numbersArray)); // [-1]
console.log(indicesOfIntegerRange(numbersArray, 40)); // [-1]
console.log(indicesOfIntegerRange(numbersArray, 50)); // [4]
console.log(indicesOfIntegerRange(numbersArray, 40, 50)); // [4]
console.log(indicesOfIntegerRange(numbersArray, 50, 40)); // [4]
Hope this would help.

Related

concat two arrays in JS with a string at index 0 in first array

the point here is to join two arrays and ultimately calculate the amplitude. the console logs error error, followed by NaN.. what am I doing wrong? If i move the error element in the first array to the middle of the array, this works fine. it also works if i concat the first array to the second array, but i would like to make this work as similarly as the way it is written below.
const temperatures = ['error', 3, -2, -6, -1, 9, 13, 17, 15, 14, 9, 5];
const temperatures2 = [45, 23, 12, 2, 4, 6, 9, 78, 13, 15];
const tempMerge = temperatures.concat(temperatures2);
const calcTempAmplitude = function (temps) {
let max = temps[0];
let min = temps[0];
for (let i = 0; i < temps.length; i++) {
const currTemp = temps[i];
if (typeof currTemp !== 'number') {
continue;
}
if (temps[i] > max) {
max = currTemp;
}
if (temps[i] < min) {
min = currTemp;
}
}
console.log(max, min);
return max - min;
};
const amplitude = calcTempAmplitude(tempMerge);
console.log(amplitude);
Try using the spread operator:
const amp = Math.max(...temperatures, ...temperatures2) - Math.min(...temperatures, ...temperatures2);
EDIT:
Filter the arrays for only numbers:
const amp = Math.max(...temperatures.filter(x => typeof x === "number"), ...temperatures2.filter(x => typeof x === "number")) - Math.min(...temperatures.filter(x => typeof x === "number"), ...temperatures2.filter(x => typeof x === "number"));
In your code, I don't know what output you are expecting, but by modifying the code of line no. 3, I am able to get the output "84".
Here is the line no. 3 code:
const tempMerge = temperatures.filter(temp => typeof temp === 'number').concat(temperatures2);
What I did is just filtered out non-number data from 'temperatures' variable.
Here is the full running code on JSBin: https://jsbin.com/dofoxuf/edit?js,console

Function if and for loop for even numbers in const array

i have exercise like this : You have the table: const numbers = [2, 5, 7, 10, 34, 16, 879, 1]. Write a function that will print in the console a new table containing only even numbers from the numbers table. And mine solution is :
function evenNumbers(numbers){
for ( let num of numbers)
if (num / 2) }
I don't know is that function "if" is correct for "even" numbers, i also don't know for sure that i grab "const numbers" to function. i hope for a help
so now with "filter" i have :function evenNumbers(number){
return number % 2 === 0}
const parzyste = numbers.filter(evenNumbers)
console.log(parzyste)
is that correct after edition?
To check if a number is even or odd, you need to check the remainder of it over 2 and to do so you can use % operator:
if (num%2 === 0) {
// number is even, because the remainder is 0
}
else {
// number is odd
}
You can use the array filter() to filter the even numbers using the condition num % 2 == 0
const numbers = [2, 5, 7, 10, 34, 16, 879, 1];
function evenNumbers(numbers) {
return numbers.filter(n => n % 2 == 0);
}
console.log(evenNumbers(numbers));
Alternatively, with if condition as below
const numbers = [2, 5, 7, 10, 34, 16, 879, 1];
function evenNumbers(numbers) {
let evenNums = [];
numbers.forEach(n => {
if (n % 2 == 0) {
evenNums.push(n);
}
});
return evenNums;
}
console.log(evenNumbers(numbers));

How to limit for 10 results the array.filter?

I have big array, I want to make an autocomplete search, but I want to display only 10 results, so stop iterating through the array by the time there were found 10 results. I have made this:
let items = array.filter(r => r.indexOf(term)!=-1);
console.log(items.length) // lots of items, need to be limited to 10
It works but I don't know how to stop the array.filter by the time it reaches the desired limit.
You could use another variable to keep track of how many items matched the condition so far and always return false after the limit has been reached. Here is an example:
const arr = [1,0,2,0,3,0,4,5,6,7,8,9,10,11,12,13,14];
const filtered = arr.filter(function(item) {
if (this.count < 10 && item > 0) {
this.count++;
return true;
}
return false;
}, {count: 0});
console.log(filtered);
Here, I'm using an object {count: 0} as the context of the callback function. You can find out more about Array.filter from here
Basically you can use a generator function, which can be stopped by a self made limit, like in the below function
function *filter(array, condition, maxSize) {
if (!maxSize || maxSize > array.length) {
maxSize = array.length;
}
let count = 0;
let i = 0;
while ( count< maxSize && i < array.length ) {
if (condition(array[i])) {
yield array[i];
count++;
}
i++;
}
}
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log( Array.from( filter(array, i => i % 2 === 0, 2 ) ) ); // expect 2 & 4
So it will stop after it reaches maxSize as a parameter, and to easily return it into an array, you can use Array.from, which will iterate the iterator of the generator function
You could hand over a counter and omit any other values for filtering.
const
filter = v => v % 2,
filterMax = (fn, c) => x => c && fn(x) && c--,
max = 3,
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
result = array.filter(filterMax(filter, max));
console.log(result);
Taking the idea of Icepickle's answer a bit ahead with a loop for finding the next valid item and yield this one.
function* filterMax(array, cb, count) {
var i = 0;
while (count) {
while (i < array.length && !cb(array[i])) i++;
if (i >= array.length) return;
yield array[i++];
count--;
}
}
const
filter = v => v % 2,
max = 3,
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(...filterMax(array, filter, max));
You can't break from Array.prototype.filter method. It will loop over every element. You can use a simple for loop and break when 10 items are found
const items = []
for (const value of array) {
if (value.includes(term))
items.push(value)
if (items.length === 10)
break;
}
Just for the trick :
EDIT : To clarify this code will pick the 10 first even number of the list
let array = [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, 26, 27, 28, 29, 30];
const result = array.reduce((temp, value) => {
if(value%2==0 && temp.length<10)
temp.push(value);
return temp;
}, []);
console.log(result);
var data = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14"]
var limited = data.filter((val,i)=>i<10)
console.log(limited)
You can do this just simple add .Slice(0,NO_OF_ELE_WANT)
eg. finding first two even no
[1,2,3,4,5,6,7,8,9,10].filter((e)=> e%2==0).slice(0,2)
Answer : let items = array.filter(r => r.indexOf(term)!=-1).slice(0,10);
I wrote a library that's handy for this sort of thing.
Here's how I'd find the first 100 numbers that start with the character "1"
const {blinq, range} = window.blinq;
//create a large array of strings to search
const arrToBeSearched = range(0,10000)
.select(x => `${x}`)
.toArray()
const query = blinq(arrToBeSearched)
.where(x => x.startsWith("1"))
.takeWhile((x, i) => i < 100)
const result = [...query] //no calculation until we materialize on this line
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/blinq"></script>
I know its a bit late, but here's for the new comers!
// we'll create a function which will take two arguments
// first argument would be your original array which your want to filter from
// second argument would be the number of results you want the filter to return
const limitedArray = (originalArray, limit) => {
let newArray = [];
for (let item of originalArray) {
if (newArray.length >= limit) break;
//your code here
//in my case i'll jush push in to the array
newArray.push(item)
}
return newArray;
};
//---------------->ignore v<-------------------
//the above function would return an array so in other words we can see this function as an array
const array = [1, 2, 3, 4, 5, 6, 'cascas', 'ascasc', 9, 10, 'ascs'];
console.log(limitedArray(array, 4));
//similarly
limitedArray(array, 4).forEach(item => {
console.log(item)
})
You can define your custom method on Array.prototype which will take 2 arguments. A callback and a max elements that result array will contain.
The code below gets the first 3 odd numbers from array.
function filterUpto(callback,max){
let len = this.length
let res = [];
let i = 0;
while(res.length < max && i < len){
if(callback(this[i],i,this)) res.push(arr[i])
i++
}
return res;
}
Object.defineProperty(Array.prototype,'filterUpto',{
value:filterUpto
})
let arr = [1,2,3,4,5,6,7,8,9,10];
console.log(arr.filterUpto(x => x % 2,3)); //first three odd numbers
Here is another possible solution, pretty straightforward, using Array.from:
const arr = [
"foo",
"bar",
"foobar",
"baz",
"foobaz",
"artefact",
"mortar",
"bar",
"arity",
"mark",
"car",
"dare",
"arbitrary",
"tar",
"jar",
"war",
];
const filterWithLimit = (arr, value, length) =>
Array.from(
{ length },
function () {
return arr
.slice(this.index++)
.find((option, i) => (this.index += i, option.includes(value)));
},
{ index: 0 }
);
console.log(filterWithLimit(arr, "ar", 10));
Here is a short solution which doesn't continue searching after the limit is reached:
function filter_n(array, limit, test) {
let ret = []
array.find((x)=> test(x) && ret.push(x)>=limit )
return ret
}
when test(x) is true, it calls ret.push(x) (which adds x to ret and outputs the length of ret)
then, once ret's length is >= limit, the inner function returns true, and find stops looping because it "found" a result

How to write the code with less time complexity for finding the missing element in given array range?

My function should return the missing element in a given array range.
So i first sorted the array and checked if the difference between i and i+1 is not equal to 1, i'm returning the missing element.
// Given an array A such that:
// A[0] = 2
// A[1] = 3
// A[2] = 1
// A[3] = 5
// the function should return 4, as it is the missing element.
function solution(A) {
A.sort((a,b) => {
return b<a;
})
var len = A.length;
var missing;
for( var i = 0; i< len; i++){
if( A[i+1] - A[i] >1){
missing = A[i]+1;
}
}
return missing;
}
I did like above, but how to write it more efficiently??
You could use a single loop approach by using a set for missing values.
In the loop, delete each number from the missing set.
If a new minimum value is found, all numbers who are missing are added to the set of missing numbers, except the minimum, as well as for a new maximum numbers.
The missing numbers set contains at the end the result.
function getMissing(array) {
var min = array[0],
max = array[0],
missing = new Set;
array.forEach(v => {
if (missing.delete(v)) return; // if value found for delete return
if (v < min) while (v < --min) missing.add(min); // add missing min values
if (v > max) while (v > ++max) missing.add(max); // add missing max values
});
return missing.values().next().value; // take the first missing value
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));
Well, from the question (as it's supposed to return a single number) and all the existing solution (examples at least), it looks like list is unique. For that case I think we can sumthe entire array and then subtracting with the expected sum between those numbers will generate the output.
sum of the N natural numbers
1 + 2 + ....... + i + ... + n we can evaluate by n * (n+1) / 2
now assume, in our array min is i and max is n
so to evaluate i + (i+1) + ..... + n we can
A = 1 + 2 + ..... + (i-1) + i + (i+1) + .... n (i.e. n*(n+1)/2)
B = 1 + 2 + ..... + (i-1)
and
C = A - B will give us the sum of (i + (i+1) + ... + n)
Now, we can iterate the array once and evaluate the actual sum (assume D), and C - D will give us the missing number.
Let's create the same with each step at first (not optimal for performance, but more readable) then we will try to do in a single iteration
let input1 = [2, 3, 1, 5],
input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10],
input3 = [3, 4, 5, 6, 8];
let sumNatural = n => n * (n + 1) / 2;
function findMissing(array) {
let min = Math.min(...array),
max = Math.max(...array),
sum = array.reduce((a,b) => a+b),
expectedSum = sumNatural(max) - sumNatural(min - 1);
return expectedSum - sum;
}
console.log('Missing in Input1: ', findMissing(input1));
console.log('Missing in Input2: ', findMissing(input2));
console.log('Missing in Input3: ', findMissing(input3));
Now, lets try doing all in a single iteration (as we were iterating 3 times for max, min and sum)
let input1 = [2, 3, 1, 5],
input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10],
input3 = [3, 4, 5, 6, 8];
let sumNatural = n => n * (n + 1) / 2;
function findMissing(array) {
let min = array[0],
max = min,
sum = min,
expectedSum;
// assuming the array length will be minimum 2
// in order to have a missing number
for(let idx = 1;idx < array.length; idx++) {
let each = array[idx];
min = Math.min(each, min); // or each < min ? each : min;
max = Math.max(each, max); // or each > max ? each : max;
sum+=each;
}
expectedSum = sumNatural(max) - sumNatural(min - 1);
return expectedSum - sum;
}
console.log('Missing in Input1: ', findMissing(input1));
console.log('Missing in Input2: ', findMissing(input2));
console.log('Missing in Input3: ', findMissing(input3));
Instead of sorting, you could put each value into a Set, find the minimum, and then iterate starting from the minimum, checking if the set has the number in question, O(N). (Sets have guaranteed O(1) lookup time)
const input1 = [2, 3, 1, 5];
const input2 = [2, 3, 1, 5, 4, 6, 7, 9, 10];
const input3 = [3, 4, 5, 6, 8];
function findMissing(arr) {
const min = Math.min(...arr);
const set = new Set(arr);
return Array.from(
{ length: set.size },
(_, i) => i + min
).find(numToFind => !set.has(numToFind));
}
console.log(findMissing(input1));
console.log(findMissing(input2));
console.log(findMissing(input3));
If the array is items and the difference between missing and present diff is 1:
const missingItem = items => [Math.min(...items)].map(min => items.filter(x =>
items.indexOf(x-diff) === -1 && x !== min)[0]-diff)[0]
would give complexity of O(n^2).
It translates to: find the minimum value and check if there isn't a n-diff value member for every value n in the array, which is also not the minimum value. It should be true for any missing items of size diff.
To find more than 1 missing element:
([Math.min(...items)].map(min => items.filter(x =>
items.indexOf(x-diff) === -1 && x !== min))[0]).map(x => x-diff)
would give O((m^2)(n^2)) where m is the number of missing members.
Found this old question and wanted to take a stab at it. I had a similar thought to https://stackoverflow.com/users/2398764/koushik-chatterjee in that I think you can optimize this by knowing that there's always only going to be one missing element. Using similar methodology but not using a max will result in this:
function getMissing(arr) {
var sum = arr.reduce((a, b) => a + b, 0);
var lowest = Math.min(...arr);
var realSum = (arr.length) * (arr.length + 1) / 2 + lowest * arr.length;
return realSum - sum + lowest;
}
With the same inputs as above. I ran it in jsperf on a few browsers and it is faster then the other answers.
https://jsperf.com/do-calculation-instead-of-adding-or-removing.
First sum everything, then calculate the lowest and calculate what the sum would be for integers if that happened to be the lowest. So for instance if we have 2,3,4,5 and want to sum them that's the same as summing 0,1,2,3 and then adding the lowest number + the amount of numbers in this case 2 * 4 since (0+2),(1+2),(2+2),(3+2) turns it back into the original. After that we can calculate the difference but then have to increase it once again by the lowest. To offset the shift we did.
You can use while loop as well, like below -
function getMissing(array) {
var tempMin = Math.min(...array);
var tempMax = tempMin + array.length;
var missingNumber = 0;
while(tempMin <= tempMax){
if(array.indexOf(tempMin) === -1) {
missingNumber = tempMin;
}
tempMin++;
}
return missingNumber;
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));
My approach is based on in place sorting of the array which is O(N) and without using any other data structure.
Find the min element in the array.
Sort in place.
Again loop the array and check if any element is misplaced, that is the answer!
function getMissing(ar) {
var mn = Math.min(...ar);
var size = ar.length;
for(let i=0;i<size;i++){
let cur = ar[i];
// this ensures each element is in its right place
while(cur != mn +i && (cur - mn < size) && cur != ar[cur- mn]) {
// swap
var tmp = cur;
ar[i] = ar[cur-mn];
ar[cur-mn] = tmp;
}
}
for(let i=0; i<size; i++) {
if(ar[i] != i+mn) return i+mn;
}
}
console.log(getMissing([2, 3, 1, 5]));
console.log(getMissing([2, 3, 1, 5, 4, 6, 7, 9, 10]));
console.log(getMissing([3, 4, 5, 6, 8]));

Split 100 numbers into N same length parts

Specify how many numbers you want to show.
E.g. if
you specify 2, the result should be 0 and 100. If you specify 3, the numbers should be 0, 50 and 100. If you specify 4, the numbers should be 0, 33, 67, 100 etc.
There should always be the same length between every displayed number.
The for-loop solution:
const run = (max, num) => {
let result = [];
let part = max / (num - 1);
for(let i = 0; i < max; i += part) {
result.push(Math.round(i));
}
result.push(max);
return (result);
};
console.log(run(100, 4)); // [0, 33, 67, 100]
console.log(run(100, 5)); // [0, 25, 50, 75, 100]
console.log(run(100, 7)); // [0, 17, 33, 50, 67, 83, 100]
If you can use es6 this is a nice functional one-liner to do it:
const fn = (n, l) => [...Array(n)].map((i, id) => Math.floor(l/(n-1) * id))
console.log(fn(4,100))
console.log(fn(2,100))
Of course you can't always have the exact distance between numbers when you want integers — you need to round somewhere when the number doesn't evenly divide.
function numbers(number){
var max=100;
spacing = Math.floor( max/ (number-1) );
var returnMe = [0];
var cur=spacing;
while(cur <= max){
returnMe.push( cur );
cur+=spacing;
}
return returnMe;
}

Categories

Resources