Im learning Javascipt and actually im on episode with array methods.
My imaginary exercise relies on found the Max/Min value in array by array.find method.
Acutally I did smth like that, but script returned me "Undefined".
Please help. :)
const scores = [10, 20, 30, 22, 25, 109, 90];
const maxScore = scores.find(score => {
let max = 0;
for (let i=1; i < scores.length; i++){
if(score[i] > max){
max = score[i];
};
};
return max;
});
console.log(maxScore);
P.S. I know about "Math.max.apply", but I have to do it by array.find and simple loop.
You could take a closure over an index for looping from the end and a temporary max value which is at start undefined and gets the first value from the first element.
Then loop while the value at temp index is smaller than score, store this value in max, repeat.
At the end return the result if index plus one is equal to the temp index.
This approach takes a single loop. find iterates from start of the array and the inner loop from the end of the array if both indices cross, the result is found.
const
scores = [100, 20, 30, 22, 25, 109, 90],
maxScore = scores.find(
((j, max) => (score, i, array) => {
if (max === undefined) {
max = score;
j = array.length;
}
if (score < max) return;
while (array[j - 1] < score) max = array[--j];
return i + 1 === j;
})
()
);
console.log(maxScore);
The simplest way to do it, without using any Array methods, can be written as:
const maxScore = (scores) => {
let score = 0;
for ( let i = 0; i < scores.length; i++ ) {
if(scores[i] > score) {
score = scores[i]
}
}
return score;
}
From MDN:
The find() method returns the value of the first element
in the provided array that satisfies the provided testing function.
Lets redefine our simple function again,
const maxScore = scores => {
let score = Number.NEGATIVE_INFINITY;
scores.forEach(element => {
let acc = scores.find(number => number > score);
if(!isNaN(acc)) {
score = acc;
}
})
return score;
}
find works on each array element. So take the max outside the find method & log max. Besides there were two typos
const scores = [10, 20, 30, 22, 25, 109, 90];
let max = 0;
const maxScore = scores.find((score) => {
for (let i = 1; i < scores.length; i++) {
if (scores[i] > max) {
max = scores[i];
};
};
return max;
});
console.log(max)
Try this:
const scores = [10, 20, 30, 22, 25, 109, 90];
let max = 0;
scores.find(score => { if(score > max) max = score });
console.log(max);
Your current code is looping the scores array whilst its already looping it, JavaScripts .find, essentially loops the array.
const scores = [10, 20, 30, 22, 25, 109, 90];
scores.reduce(function(a,b) { return a > b ? a : b });
// 109
Related
I am trying to write a simple "getRandomIndex" function to return a random and unused index number for a given array but I get "Maximum call stack size exceeded" error at let rndIdx = Math.floor(Math.random() * (arr.length - 0)) + 0;.
const arr = [81, 33, 45, 22, 97, 19, 60];
const usedIndexes = []; // I am trying to store used indexes here
function getRandomIndex() {
let rndIdx = Math.floor(Math.random() * (arr.length - 0)) + 0;
if(usedIndexes.includes(rndIdx)) {
getRandomIndex();
return;
} else {
usedIndexes.push(rndIdx);
}
return rndIdx;
}
// if the array length is more than 10, I always get "call stack size exceed" error.
for(let i = 0; i < arr.length; i++) {
// I need to use all elements in the array eventually
console.log(getRandomIndex());
}
What I am missing?
You must check that the length of the array allows for different unused numbers.
if (usedIndexes.length>=arr.length) {
return null
}
You need to return the output of getRandomIndex() rather than calling it, dumping the output, then returning nothing (which gives you undefined)
Fixed Code
const arr = [81, 33, 45, 22, 97, 19, 60];
const usedIndexes = []; // I am trying to store used indexes here
function getRandomIndex() {
let rndIdx = Math.floor(Math.random() * (arr.length - 0)) + 0;
if(usedIndexes.includes(rndIdx)) {
// used to be
// - getRandomIndex();
// - return;
return getRandomIndex();
} else {
usedIndexes.push(rndIdx);
}
return rndIdx;
}
// if the array length is more than 10, I always get "call stack size exceed" error.
for(let i = 0; i < arr.length; i++) {
// I need to use all elements in the array eventually
console.log(getRandomIndex());
}
Output
0
2
4
3
1
6
5
I need to use function that takes an array of numbers as an argument. The function is to return the largest value from the set (variable randomNumbers). I need to assign the result of the action to a variable (result). Here below is my code which is not working and I don't know where to use the variable result.
const randomNumbers = [27, 64, 47, 78, 48, 11, 76, 25, 11, 83];
function maxFromArray(numbers) {
let max = numbers;
for (let i = 1; i < numbers.length; i++) {
if (i > max) {
max = numbers[i];
}
}return(max);
}
console.log(maxFromArray(randomNumbers));
You need as start value for max the value at index zero. Inside of the condition, you need the actual value.
The return statement needs only an expression without wrapping in parentheses.
function maxFromArray(numbers) {
let max = numbers[0]; // first item
for (let i = 1; i < numbers.length; i++) {
if (numbers[i] > max) { // take item at index
max = numbers[i];
}
}
return max; // return without parentheses
}
const randomNumbers = [27, 64, 47, 78, 48, 11, 76, 25, 11, 83];
console.log(maxFromArray(randomNumbers));
I want to write a function that takes array as an argument and returns how many numbers can be divided by 12. However, if array has a number higher than 111 then it should return 0;
I wrote this:
function isDivisble(array) {
let numberOfNum = 0;
for(let i=0; i < array.length; i++) {
if(array[i] % 12 == 0 && array[i] < 111) {
numberOfNum = numberOfNum + 1 ;
} else {
numberofNum = 0;
}
}
return console.log(numberOfNum);
}
let test = [12, 24, 36, 44, 55, 255];
isDivisble(test)
I realized that this code checks individually whether the current number is divisible and not higher than 111 and not globally whether the array has a number higher than 111, but I dont understand how to make a general array check.
Is writing for loop with if statement to check and then another for loop inside if statement makes it a little bit spaghetti?
You can use some to check if there is any element which is greater than 111 first.
Then you can use filter to get element that is divisible by 12.
Like this:
const isDivisible = (arr) => {
if (arr.some((e) => e > 111)) return 0;
return arr.filter((e) => e % 12 === 0).length;
};
const test = [12, 24, 36, 44, 55, 48];
console.log(isDivisible(test));
I've slightly modified your function that returns 0 if a number is greater than 111 else it checks if it is divisible by 12
function isDivisble(array) {
let count = 0;
for(let i=0; i<array.length; i++){
if(array[i] > 111){
return 0;
}else{
if(array[i] % 12 === 0){
count++
}
}
}
return count;
}
let test = [12, 24, 36, 44, 55, 255];
console.log(isDivisble(test));
The some array method will do the trick:
array.some(value => { return value > 111 }) will return true if any of its values is greater than 111.
You can also check if every array value respects a certain condition by using array.every with a similar callback:
array.every(value => { return value <= 111 }) is true only if every value in the array is lower than or equal to 111.
The best generic solution is the oene below
Logic
Filter the array for number greater that 111. If this filter returns an array with a length greater than 1 then return 0
Else filter the array for numbers divisible by 12. No need to check number is less than 111. Because if that number is greater than 111 the function might have already returned 0.
Retun the length of the above filter.
Working Fiddle
function isDivisbleGeneric(arr) {
const numberGreaterThanLimit = arr.filter((node) => node > 111);
let returnCount;
if(numberGreaterThanLimit.length > 0) {
returnCount = 0;
} else {
const divisibleBy12 = arr.filter((node) => node %12 === 0);
returnCount = divisibleBy12.length;
}
return returnCount;
}
let test = [12, 24, 36, 44, 55, 255];
const count = isDivisbleGeneric(test);
console.log(count);
One Line Solution
const isDivisbleOneLine = (arr) => arr.filter((node) => node > 111).length > 0 ? 0 : arr.filter((node) => node %12 === 0).length;
let test = [12, 24, 36, 44, 55, 255];
const count = isDivisbleOneLine(test);
console.log(count);
function isDivisble(array) {
// at the beginning, do from here
if (array.some(p=>p > 111)) {
return 0;
}
// Rest xxxxxx
}
I think the example is the simplest.
I have this array : [10, 30, 55, 75, 94, 112] and the value 69.
I want to get: [55, 75, 94, 112]
So I want to filter out the smaller values but keep the closest.
an idea?
Something like this using filter.
var arr = [1, 3, 5, 7, 9, 11];
var value = 6;
function remove(arr, value) {
let copy = arr;
let newArr = arr.filter((arr, index) => !((arr < value) && (copy[index + 1] < value)))
console.log(newArr)
}
remove(arr, value) // [5, 7, 9, 11]
Just filter, and check if either this or the next value in the array is >= limit
const filter=(array, limit)=>array.filter((value,index)=>value>=limit||array[index+1]>limit);
console.log(filter([10, 30, 55, 75, 94, 112], 69));
Use Array.filter, Array.pop, Array.sort Array.concat
function f(val, array){
// array.sort( (a,b)=>a-b ); // if array isn't sorted, you must be use
return array.filter(e=>e>val).concat([array.filter(e=>e<val).pop()])
}
Given an input array arr and a value val:
Iterate over arr, splicing all elements greater than val into a separate array.
Append the maximum element left in arr to the new array.
arr = [1, 3, 5, 7, 9, 11];
val = 6;
new_arr = []; // Initialize new array
for (let i=0; i<arr.length; i++) { // Iterate over current array
if (arr[i]>val) { // If the current element is greater than the given value
new_arr.push(arr.splice(i, 1)[0]) // Splice it into the new array
i--; // Decrement i so as to not skip any elements
}
}
new_arr.unshift(Math.max(...arr)) // Add the closest value to the new array
console.log(new_arr);
Start by finding the closest delta for numbers that are under the limit. Then filter all numbers that are under the limit, and the their delta with the limit is not equal to the delta you've found in the previous step.
Note: this assumes that the numbers are unique, but they don't have to be sorted.
const fn = (arr, lim) => {
const closestSmallerDelta = arr.reduce((acc, n) =>
lim < n || lim - n > acc ? acc : lim - n
, Infinity)
return arr.filter(n => lim < n || lim - n === closestSmallerDelta)
}
console.log(fn([10, 30, 55, 75, 94, 112], 69));
// unsorted array
console.log(fn([112, 55, 75, 94, 10, 30], 69));
assuming the array is always sorted:
const deleteSmallerButLastOne = (array , refNum ) =>{
const finalArr = []
for(let [index, num] of array.entries()){
if(num < refNum && array[index + 1] >= refNum) finalArr.push(num)
if(num > refNum) finalArr.push(num)
}
return finalArr
}
I took this approach instead of modifying the original array just in case you need it for later.
Here's one possible approach (apparently assuming array is sorted). The idea is to find the very first item that is greater than or equal to lim; when you found it, there's no need to check the rest of an array (and that's what all the other answers do).
function processSorted(arr, lim) {
const i = arr.findIndex(el => el >= lim);
if (i === -1) // no elements greater than lim, return just the last one
return arr.slice(-1);
if (i === 0) // the first element is greater than lim, give back 'em all!
return arr;
return arr.slice(i - 1);
}
console.log(processSorted([10, 30, 55, 75, 94, 112], 69));
It's not sorted, it's possible to sort it anyway, or, if you really strive for n-only, go with one-iteration only approach:
function processUnsorted(arr, lim) {
const res = [];
let oneLess = -Infinity,
len = arr.length;
arr.forEach(el => {
if (el >= lim) res.push(el);
else oneLess = Math.max(oneLess, el);
});
if (oneLess !== -Infinity) res.unshift(oneLess);
return res;
}
console.log(processUnsorted([30, 55, 10, 94, 75, 112], 69));
I have an array of this:
[34, 12, 56]
[100,125,19]
[30,50,69]
125 has been the highest value, it will return the index [1,1] format. Meaning 125 which is the highest value will return row 1 column 1
I was able to get the index in an array using this code
var a = [0, 21, 22, 7, 12];
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i :
iMax, 0);
document.write("indexOfMaxValue = " + indexOfMaxValue); // prints
"indexOfMaxValue = 2"
Here's my approach. It flattens out all the arrays into more managable one, finds the max number and its index, and then calculates it's position using some math. Using a single array makes this calculation much easier.
const arr = [[34, 12, 56], [100,125,19], [30,50,69]];
const arr2 = [0, 21, 22, 7, 12];
function findHighest(arr) {
// Get the number of columns
const cols = arr.length;
// Flatten out the arrays
const tempArr = arr.flatMap(el => el);
// Get the max number from the array
const max = Math.max.apply(null, tempArr);
// Find its index
const indexMax = tempArr.findIndex(el => el === max);
// Find the remainder (modulo) when you divide the index
// by the number of columns
const mod = indexMax % cols;
// Return the final array output
return [Math.floor(indexMax / cols), mod];
}
console.log(findHighest(arr))
console.log(findHighest(arr2))
This will give the expected output but not sure is it good way to solve this:
var arr = [
[34, 12, 56],
[100, 125, 19],
[30, 50, 69]
];
var maxValue, maxIndex;
arr.forEach((arr1, i) => {
arr1.forEach((value, j) => {
if (i == 0 && j == 0) {
maxValue = value;
maxIndex = [i, j]
} else {
if (maxValue < value) {
maxValue = value;
maxIndex = [i, j];
}
}
});
});
console.log("Max Number Index", maxIndex);
If you mean 2d solution, try this. Should work for dynamic length arrays
This should be extendable with a new forEach for a new dimension
[100,125,19],
[30,50,69]];
maxIndex = [-1, -1];
maxElem = 0;
input.forEach(function(arr, row) {
console.error(row);
arr.forEach(function(e, col) {
if( maxElem <= e ) {
maxElem = e;
maxIndex = [row, col];
}
})
})
console.log(maxIndex)