Is there a way to compare an integer against an array of integers? For instance, to determine if an int is larger than any of the array ints?
var array = [1, 2, 3, 4];
if(5 > array){
// do something
}
Update: I guess I meant, is 5 larger than the largest number in the array. Thanks!
You can use Math.max and apply
if (5 > Math.max.apply(Math, array)) {
// do something
}
Update: To explain as it works. It's described in the docs I linked but I will try to be more clear here:
Math.max returns the largest of zero or more numbers, so:
Math.max(1, 2, 3, 4) // returns 4
apply calls a function with a given 'this' value (the first argument) and arguments provided as an array (the second). so:
function sum(a, b) {
return a + b;
}
console.log(sum.apply(window, [2, 3])); // 5
Therefore, if you have an array of integers and you want to get the max, you can combine them to have:
console.log(Math.max.apply(Math, [1, 2, 3, 4])); // 4
Because it's exactly like have:
console.log(Math.max(1, 2, 3, 4));
The difference is you pass an array instead.
Hope it's more clear now!
There is no good and readable built in way of doing it, but it can be done simply with:
var bigger = true;
for (var i =0; i < array.length; i++) {
if (5 <= array[i]) {
bigger = false;
// you can add here : break;
}
}
Sure, you could sort the array, take the last element, and see if your integer is greater than that. Or, you could loop through and check each one. Up to you. The loop is a more performant way.
//maybe check the bounds on this if you know it can be a blank array ever
var max = myArray[0];
for(var x = 0; x < myArray.length; x++) {
max = Math.max(max, myArray[x]);
}
if(500 > max) {
//do something
}
Related
I need to create a function that take as parameter an array and a target. It should return an array of arrays where the sum of these numbers equals to the target
sumPairs(array, target) {
}
For example:
sumPairs([1, 2, 3, 4, 5], 7) // output : [[2, 5], [3, 4]]
I know I have to use map(), and probably reduce(), set(), or filter() maybe (I read their documentation in MDN but still cant find out). I tried some ways but I can't get it.
If you guys could help me to find out how to dynamically create arrays and push them into a new array..
I read there some solutions (Split array into arrays of matching values) but I hate to just use created functions without knowing what they really do or how they work.
Some very basic code for achieving it, Just run all over combinations and conditionally add the items you want.
function sumPairs(array, target) {
var res = [];
for(var i = 0; i < array.length; i++){
for(var j = 0; j < array.length; j++){
if(i!=j && array[i]+array[j]==target &&
res.filter((x)=> x[0] == array[j] && x[1] == array[i]).length == 0 )
res.push([array[i], array[j]]);
}
}
return res;
}
var result = sumPairs([1, 2, 3, 4, 5], 7);
console.log(result);
Option 2 - see this answer for more options (like using reduce)
function sumPairs(array, target) {
return array.flatMap(
(v, i) => array.slice(i+1).filter(w => (v!=w && v+w==target)).map(w=> [w,v])
);
}
var result = sumPairs([1, 2, 3, 4, 5], 7);
console.log(result);
"The exercise says that it sould be arrays of pairs that sum the
target value so I think only 2 items"
If you need a pair that matches a sum and you pick any number from the list, you are left with
the following equation to solve num + x = sum where we want to find x. E.g. if you picked 7 and the target sum is 10 then you know you are looking for a 3.
Therefore, we can first construct a counting map of the numbers available in our list linear (O(n)) time and then search for matches in linear time as well rather than brute forcing with a quadratic algorithm.
const nums = [1, 2, 3, 4, 5];
console.log(findSumPairs(nums, 7));
function findSumPairs(nums, sum) {
const countByNum = countGroupByNum(nums);
return nums.reduce((pairs, num) => {
countByNum[num]--;
const target = sum - num;
if (countByNum[target] > 0) {
countByNum[target]--;
pairs.push([num, target]);
} else {
countByNum[num]++;
}
return pairs;
}, []);
}
function countGroupByNum(nums) {
return nums.reduce((acc, n) => (acc[n] = (acc[n] || 0) + 1, acc), {});
}
Here's another implementation with more standard paradigms (e.g. no reduce):
const nums = [1, 2, 3, 4, 5];
console.log(findSumPairs(nums, 7));
function findSumPairs(nums, sum) {
const countByNum = countGroupByNum(nums);
const pairs = [];
for (const num of nums) {
const target = sum - num; //Calculate the target to make the sum
countByNum[num]--; //Make sure we dont pick the same num instance
if (countByNum[target] > 0) { //If we found the target
countByNum[target]--;
pairs.push([num, target]);
} else {
countByNum[target]++; //Didin't find a match, return the deducted num
}
}
return pairs;
}
function countGroupByNum(nums) {
const countByNum = {};
for (const num of nums) {
countByNum[num] = (countByNum[num] || 0) + 1;
}
return countByNum;
}
You can also sort your array and find all the pairs with given sum by using two pointer method. Place the first pointer to the start of the array and the second pointer to the end.
if the sum of the values at the two places is :
More than target: Decrement your second pointer by 1
Less than target: Increment your first pointer by 1
Equal to target: This is one possible answer, push them to your answer array and increment your first pointer by 1 and decrement your second pointer by 1.
This is more performant solution with complexity O(n*log(n))
I am working on a challenge and in need of some help:
Write a for loop that calculates sum of squares of items in an array of numbers. Example: For array [ 1, 2, 3, 4 ] it calculates the sum of squares as 30 (i.e. 1 + 4 + 9 + 16). I have a fiddle set up if anyone wants to have a closer look. Thanks for your help!
https://jsfiddle.net/jamie_shearman/2drt56e3/23/
var aFewNumbers = [ 1, 2, 3, 7 ];
var squareOfAFewNumbers = 0;
for( var i = 0; i <= aFewNumbers; i++ ) {
squareOfAFewNumbers = squareOfAFewNumbers * aFewNumbers[i] ;
}
console.log( squareOfAFewNumbers );
Your math is wrong. As an obvious issue, the variable starts at 0 and then is multiplied by each array element; 0 times anything is 0, so it will always remain 0 no matter what the values are. Not to mention your loop isn't looking at the length of the array as a stopping condition, which it should be, since you want to iterate from the beginning to the end of the array.
You need to iterate through to the array's length, square each array element, and add that square to the variable:
for( var i = 0; i < aFewNumbers.length; i++ ) {
squareOfAFewNumbers += aFewNumbers[i] * aFewNumbers[i];
}
If you can use ES6, you can even use higher-order array functions to simplify this more:
var squareOfAFewNumbers = aFewNumbers.reduce((result, entry) => result + entry * entry, 0);
There are multiple approaches you can take for reaching the desired result, but as you've mentioned that you must write a for loop; therefore, I sorted the answers by having that in mind.
Using the for loop
let numbers = [1, 2, 3, 7],
sum = 0;
for(let i = 0; i < numbers.length; i++) {
sum += Math.pow(numbers[i], 2)
}
// Sum is now 63
Using forEach method of the array object
let numbers = [1, 2, 3, 7],
sum = 0;
numbers.forEach(number => sum += Math.pow(number, 2))
// Sum is now 63
Oneliner
let sum = [1, 2, 3, 7].reduce((a, c) => a + Math.pow(c, 2))
The reduce method uses an accumulator to store temporary results, the accumulator is passed to the callback as the first argument and the second argument is the element's value, you can read more about the reduce method here.
You can use JavaScript pow() Method to create the square and sum it to the sumSquareOfAFewNumbers.
var aFewNumbers = [ 1, 2, 3, 7 ];
var sumSquareOfAFewNumbers = 0;
aFewNumbers.forEach(function(element) {
sumSquareOfAFewNumbers += Math.pow(element, 2);
});
console.log(sumSquareOfAFewNumbers)
Hey guys so for example I have an array:
myArray[5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2]
I'm sorting that array:
[1, 1, 1, 1, 10, 2, 2, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 9]
And I want to delete only the two duplicates so the array I want will be
[10,2,3,5,6,7,8,9]
So i'm using splice:
for (var index = 0; index < myArray.length +1; ++myArray) {
if(myArray[index+1]== myArray[index]) {
myArray.splice(index);
myArray.splice[index+1];
}
}
But when I'm pushing more of the of the numbers, the results seem unpredictable
How to do this properly?
To clarify: The purpose is to eliminate the numbers which repeat an even number of times.
Here's another method, which checks for an odd number of elements by subtracting the indexOf the key from the lastIndexOf the key after sorting:
var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];
var result = myArray.sort().filter(function(key, idx) {
return myArray.indexOf(key) === idx && //handle first instance only
(myArray.lastIndexOf(key) - myArray.indexOf(key)) % 2 === 0;
});
console.log(result);
Here is an ECMAScript2015 solution:
var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];
var count = myArray.reduce((count, num) =>
(count[num] = (count[num] || 0) + 1, count), {});
myArray = Object.keys(count).filter(num => count[num] % 2).map(Number);
console.log(myArray);
The count variable is an object of which the properties are the numbers in the original array. The value for each of these properties is the number of occurrences of that number in the original array.
The keys are then iterated to get only those into the final array that have a value (i.e. occurrences) that is odd. As object properties are iterated in numerical order (when numerical), the result is automatically sorted numerically.
About your code:
The for loop you have, has some issues:
for (var index = 0; index < myArray.length +1; ++myArray) {
if(myArray[index+1]== myArray[index]) {
myArray.splice(index);
myArray.splice[index+1];
}
}
Certainly you don't want to increment myArray, but index.
The boundary condition should not be length+1 but length-1 as in the body you have myArray[index+1] and don't want to go out of bounds there.
But more importantly, doing splice in your for loop will make the elements shift position, and as you then still increment index, you will skip elements.
In short, you should not use splice in such a loop. You can solve this by going in the reverse direction, and start at the end of the array working towards the beginning.
But the above proposed code does not have this problem and also saves you the step of sorting.
You can do this with two reduce and Object.keys(). First add values to object and then check each value with % 2 and add to array.
var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];
var obj = myArray.reduce(function(o, e) {
o[e] = (o[e] || 0)+1;
return o;
}, {})
var result = Object.keys(obj).reduce(function(r, e) {
if(obj[e] % 2) r.push(Number(e));
return r;
}, []);
console.log(result)
I'm stuck on how to find the max value of an array recursively in javascript. I tried it first iteratively and of course it works. recursively, I wanted to try it with a subroutine first, and then without a subroutine. What's the best way to call the subroutine inside itself? Where I am getting tripped up is that I want to look inside the indices, but currently my subroutine accepts an array as a parameter.
function maxValue(arr) {
var max = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
console.log(maxValue([2, 7, 8, 3, 1, 4])); //returns 8
function maxValueRecursive(arr) {
var length = arr.length; //6
var max = 0;
function doSearch(arr) {
if (arr.length === 1) {
max = arr[0];
} else { // true
max = Math.max(arr[length - 1], arr[length - 2]);
//max = Math.max(4, doSearch()) = 4.
}
return max;
}
return doSearch(arr);
}
console.log(maxValueRecursive([2, 7, 8, 3, 1, 4])) //returns 4
You can use Math.max and solve for a smaller bit of the array at each step. The trick is to remove some (any) item from the array and use Math.max to compare the item with findmax on the smaller array:
function findmax(arr){
if (arr.length == 1){
// base case - single item in array is always max
return arr[0];
}
// recursive call on smaller problem (shorter array)
return Math.max(arr[0], findmax(arr.slice(1)))
}
I used slice but you can use pop or whatever method to remove an item and compare it using Math.max as I did.
For the array [1, 4, 2, 3] the recursion unfolds as follows:
1. findmax([1, 4, 2, 3]
2. Math.max(1, findmax([4, 2, 3]))
3. Math.max(1, Math.max(4, findmax([2, 3])))
4. Math.max(1, Math.max(4, Math.max(2, findmax([3]))))
5. Math.max(1, Math.max(4, Math.max(2, 3))) // 4
For doing it without a subroutine, consider that the maximum of a one-array element is the element itself.
You want to break down the problem such that you can get the input array down to one element, and then start working backwards and checking if there are any larger elements.
Some pseudocode to get you started:
max (A[1, 2, ..., n])
if n = 1
return A[1]
else
oldMax <- max([2, ..., n])
if A[1] > oldMax
return A[1]
else
return oldMax
This may be a bit intimidating at first, but here's an explanation. We know how to get the maximum of an array with one element, so we keep doing the recursive call until we have an array with one element, But here's the trick: the array we pass into the recursive call is the same array, but with the first element removed. This way, we're making the array smaller and smaller until there's only one element left. Then, we know that the maximum is the element itself.
So we get the maximum of the one-element array, and we return that value. Now we're peeling back each layer of recursion as we try to find the biggest value.
Say the array is [1, 2, 3, 4]. Then the function will keep making recursive calls like this:
max([1, 2, 3, 4])
max([2, 3, 4])
max([3, 4])
max([4]) -> 4
At the last stage, we can return 4 since that's the maximum. But now we're back at the stage where the array is [3, 4]. At this stage, we will check to see if the first element, 3, is bigger than the maximum we computed from the recursive call, 4. In this case, it isn't, so we keep returning 4.
We repeat this until we're back at the first layer, where we finally return 4 since 1 is not greater than the maximum so far, 4. Since none of the elements in the array are greater than 4, the maximum never changed.
I know it feels weird at first, but calling a function from within itself is as simple as... well, calling it from within itself!
The below function takes the array as the first parameter, the next two parameters are the indices of the max value at that point in the search and the next value to compare the max value to respectively. You start off by using 0 and 1 and then let the function take over from there.
var findMax = function (array, curMaxIndex, nextIndex) {
if (array[nextIndex] > array[curMaxIndex]) {
curMaxIndex = nextIndex;
}
if (nextIndex > array.length) {
return array[curMaxIndex];
}
return findMax(array, curMaxIndex, nextIndex + 1);
}
var max = findMax([2, 7, 8, 3, 1, 4, 9], 0, 1);
console.log(max); //9
You could also set up default values, so the original call is more simple:
var findMax = function (array, curMaxIndex, nextIndex) {
curMaxIndex = typeof curMaxIndex !== 'undefined' ? curMaxIndex : 0;
nextIndex = typeof nextIndex !== 'undefined' ? nextIndex : 1;
if (array[nextIndex] > array[curMaxIndex]) {
curMaxIndex = nextIndex;
}
if (nextIndex > array.length) {
return curMaxIndex;
}
return findMax(array, curMaxIndex, nextIndex + 1);
}
var max = findMaxIndex(array);
The best way though is to use the built in Math.max(), which it appears you've already heard of, so I'm assuming this is just a learning exercise.
Practicing callbacks & higher ordered function & found this question online.
var merge = function(array1, array2, callback){
//your code here.
}
var x = merge([1, 2, 3, 4], [5, 6, 7, 8], function(a, b){
return a + b;
});
//x should now equal [6, 8, 10, 12].
Here's my take on this problem.
var merge = function(array1, array2, callback){
for(var i = 0; i < array1.length; i++) {
callback(array1[i], array2[i]);
}
}
var x = merge([1, 2, 3, 4], [5, 6, 7, 8], function(a, b){
return a + b;
});
When I console.log(x), the console returns "undefined" so I'm guessing it has to do w/ the value of x not being an array. I can see that the math is being done correctly though, for when I change "return a + b" to "console.log(a + b)" I get the right numbers but just not in array form. Can anyone point me towards the right direction?
You are calling the callback, but you are ignoring the value returned by it. You should accumulate all the values in an array and your should return the array from merge.
For example,
function merge(array1, array2, callback) {
// Define an array object to accumulate the results from `callback`
var result = [];
for (var i = 0; i < array1.length; i++) {
// Accumulate the result of `callback` in `result` array
result.push(callback(array1[i], array2[i]));
}
// Return the `result` array
return result;
}
Note: If the arrays are of different sizes then running the loop based on array1's length will not be correct always. So, you might want to either
go with the smallest length of two arrays and ignore elements from the longer array
or use a default value for the elements of the shorter array.
If you choose go with the first method, then you just need to adjust the loop condition, like this
var minLen = Math.min(array1.length, array2.length);
for (var i = 0; i < minLen; i++) {
...
If you choose to go with the second method, then you need to run till the maximum of two arrays and use default values, like this
var maxLen = Math.max(array1.length, array2.length);
for (var i = 0; i < maxLen; i++) {
result.push(callback(array1[i] || 0, array2[i] || 0));
}
Here, if the value of array1[i] returns undefined (if the index is not found in an array, undefined will be returned), it means that array1 is shorter than array2, so the default value 0 will be used.