0

I am expecting this code to return 4 as the maximum value of the array on obj.key, however the code below but returns 1.

Can someone help fix this, and achieve this in a shorter way?

var obj = {
  key: [1, 2, 4]
}
function getLargestElementAtProperty(obj, key) {
   if (!Array.isArray(obj[key])) {
      return undefined
   }
   for (num in obj[key]) {
      return Math.max(obj[key][num])
   }
}

var output = getLargestElementAtProperty(obj, 'key');
console.log(output); // --> expected 4
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
Carlos Franco
  • 58
  • 1
  • 1
  • 11
  • 4
    What does `Math.max` do when passed only one parameter? What does `return` do? When you debugged through it, what did you discover? – mjwills Feb 06 '19 at 23:17
  • return Math.max(obj[key][num]) <-- you return right away..... Also not sure what you think Math.max() does.... – epascarello Feb 06 '19 at 23:27
  • Probably should be a dupe of https://stackoverflow.com/questions/1379553/how-might-i-find-the-largest-number-contained-in-a-javascript-array – epascarello Feb 06 '19 at 23:29
  • ok i see now, i used .apply and i removed the for loop and instead used an else statement and it worked – Carlos Franco Feb 06 '19 at 23:31

3 Answers3

2

The issue is that a function can only return once. So when you first iterate over the array and get one then it returns and the function is done running. Math.max() returns the max from 0 or more numbers, so if you only pass it one number it will always return that same number. Something like below will work.

const obj = {
  key: [1, 2, 4]
}
function getLargestElementAtProperty(obj, key) {
  let largest;
   if (!Array.isArray(obj[key])) {
      return undefined
   }
   for (num in obj[key]) {
      if (!largest || largest < obj[key][num]) {
        largest = obj[key][num];
      }
   }
   return largest;
}

var output = getLargestElementAtProperty(obj, 'key');
console.log(output); // --> expected 4

Also if you can use Math.max and the spread operator to achieve the same thing in a more modern JavaScript way like so:

const obj = {
  key: [1, 2, 4]
}
function getLargestElementAtProperty(obj, key) {
   if (!Array.isArray(obj[key])) {
      return undefined
   }
   return Math.max(...obj[key]);
}

var output = getLargestElementAtProperty(obj, 'key');
console.log(output);

Hope that helps!

CascadiaJS
  • 2,320
  • 2
  • 26
  • 46
1

Your function returns 1 because the for .. in loop immediately returns the first item iterated in the array obj[key].

Consider revising your code by using the Array#reduce method as detailed to below, to find and return the maximum value of the input array:

var obj = {
  key: [1, 2, 4]
}
function getLargestElementAtProperty(obj, key) {
   if (!Array.isArray(obj[key])) {
      return undefined
   }
   
   var array = obj[key];
   
   /*
   Use reduce to iterate through each item in the array, comparing
   it with the previously found max value. Note that the first 
   iteration will find the max of the Math.max(1,1), which will 1
   */
   var max = array.reduce(function(currentMax, currentItem) {
      return Math.max(currentMax, currentItem)
   })
   
   return max;
}

var output = getLargestElementAtProperty(obj, 'key');
console.log(output); // --> expected 4
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
0

So I found the solution which was removing the for loop and using .apply with Math.max and my code was accepted, thanks for the help guys So this is my new code !

var obj = {
  key: [1, 2, 4]
}
function getLargestElementAtProperty(obj, key) {
   if (!Array.isArray(obj[key]) || obj[key].length === 0) {
      return undefined
   } else{
      return Math.max.apply(null, obj[key])
   }
}

var output = getLargestElementAtProperty(obj, 'key');
console.log(output); // --> expected 4
Carlos Franco
  • 58
  • 1
  • 1
  • 11