1

So I'm a JS newbie and am trying to figure out how to fix my problem. I am trying to loop over an object and return the lowest number.

in my var shortest = ; if I hardcode a number say var shortest = 455; then the problem returns the correct number 3. although im not sure what to put there to make it blank by default. I have tried object[0], object[key] and '' and none of these work properly

var myObj = {first: 45, second: 23, third: 3, fourth: 222, fifth: 2343};

var myFunc = function (object) {
    var shortest = ;
    for (var key in object) {
      if (object[key] < shortest) {
        shortest = object[key];
      }
    }; 
    return shortest;
};
jstone
  • 435
  • 3
  • 8
  • 18
  • 1
    How about putting a really big number? How about `Infinity`? This question sure looks a lot like your previous one. Are these homework questions? – cookie monster Dec 23 '13 at 02:01
  • They are, just problems im creating trying to learn this lovely language :) I could hardcode the number, but that doesn't work in the real world, so trying to understand what the proper way to do it is. – jstone Dec 23 '13 at 02:03
  • Why doesn't it work in the real world? – cookie monster Dec 23 '13 at 02:04

4 Answers4

2

set initial value of shortest to Number.MAX_VALUE is all you need

var myObj = {first: 45, second: 23, third: 3, fourth: 222, fifth: 2343};

var myFunc = function (object) {
    var shortest = Number.MAX_VALUE;
    for (var key in object) {
      if (object[key] < shortest) {
        shortest = object[key];
      }
    }; 
    return shortest;
};

Number.MAX_VALUE The largest positive representable number.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

qiu-deqing
  • 1,323
  • 7
  • 13
  • 1
    +1 for actually answering the question. A bit more help would be to point out that when *x* is undefined, the result of `x < anyNumber` is always false (see [The Abstract Relational Comparison Algorithm](http://ecma-international.org/ecma-262/5.1/#sec-11.8.5)) since *undefined* will be converted to `NaN`. – RobG Dec 23 '13 at 02:42
  • thanks for your feedback. forget to handle undefined is a common source of bug :) – qiu-deqing Dec 23 '13 at 02:53
  • Thanks this helped a lot. I read the MDN doc and what does `MIN_value` mean as it said `Number.MIN_VALUEThe smallest positive representable number - that is, the positive number closest to zero (without actually being zero).` and I don't really get it. I ran it against my code and it gave back `5e-324` in the console. – jstone Dec 23 '13 at 03:40
  • @jstone 5e-324 is a float number: 5 multiply 0.1 324 times like: 0.000000005 you can read the detail here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Floating-point_literalsyou – qiu-deqing Dec 23 '13 at 03:49
1

Try this:

var myObj = {first: 45, second: 23, third: 3, fourth: 222, fifth: 2343};

    var myFunc = function (object) {
        var shortest = object.first;
        for (var key in object) {
          if (object[key] < shortest) {
            shortest = object[key];
          }
        }; 
        return shortest;
    };
Ringo
  • 3,795
  • 3
  • 22
  • 37
  • Given the use-case, it isn't safe to assume there is a key called `first`. – loganfsmyth Dec 23 '13 at 02:07
  • You'd really not want to hardcode a property. To take this approach, you'd need to initialize the variable in the first iteration of the loop, either using a flag, or by checking `shortest` for `undefined`. – cookie monster Dec 23 '13 at 02:09
  • You should not rely on setting *shortest* to some random value. What if `object.first === NaN` or `undefined`? Also, please explain answers rather than simply posting code. – RobG Dec 23 '13 at 02:44
  • Sorry for my English! But I just follow OP question. I think first key must be valid in this case. It's not random key, right? – Ringo Dec 23 '13 at 02:49
1

The reason it fails is in here:

var myFunc = function (object) {
    var shortest = ;
    for (var key in object) {
      if (object[key] < shortest) {

Since the value of shortest is undefined, the < operator causes it to be converted to NaN for the test, and according to the rules for The Abstract Relational Comparison Algorithm, comaring anything to NaN returns undefined, which is equivalent to false here.

The fix is to initialise shortest to some value, e.g. as qiu-deqing suggested Number.MAX_VALUE, or you can use something like:

function getShortest(object) {
    var shortest, value;

    for (var key in object) {
      value = object[key];

      if (typeof value == 'number' && !isNaN(value)) {

        if (typeof shortest != 'number') {
          shortest = value;
        } else {
          if (value < shortest) {
            shortest = value;
          }
        }
      }
    }
    return shortest;
}

The above will ensure that you only compare numbers and that shortest will only be a number or undefined. There should probably be a hasOwnProperty test too to avoid inherited properties.

RobG
  • 142,382
  • 31
  • 172
  • 209
0

See if this helps:

var lowest = function(ns) {
  return Math.min.apply(0, ns);
};

var values = function(obj) {
  var result = [];
  for (var i in obj) {
    result.push(obj[i]);
  }
  return result;
};

var result = lowest(values(myObj));

console.log(result); //=> 3
elclanrs
  • 92,861
  • 21
  • 134
  • 171