2

I am using jQuery to pull some data from a web page, it comes back as an array with the following values (.5, .25, 1.25, 3.75) which I am trying to add. Here's my code snippet:

var th = 0;
    for (thisrow in objGrid) {
        var hours = objGrid[thisrow]['hours'];
        th = th+parseFloat(hours);
        console.log(hours);

        $("#msgbox").html("Showing records for week: " + thisDate + ". Total Hours for the week : " + th);
   }

in console.log I am getting this for the hours - 0, 0 , 1, 3 and it is totaling 4. If I don't use parseFloat I still get the same results, (thought I would get NaN). What am I doing wrong?

PruitIgoe
  • 6,166
  • 16
  • 70
  • 137
  • Please show your data. If `objGrid` is an Array as you seem to suggest, then you shouldn't be using a `for-in` statement. – user113716 Feb 09 '11 at 18:31
  • retract answer. as patrick dw says, what exactly is objGrid. – KJYe.Name Feb 09 '11 at 18:36
  • @patrick dw - objGrid is an Object or associative array, sorry if what I typed was misleading. – PruitIgoe Feb 09 '11 at 18:40
  • 2
    The result you're getting is odd. Can you please post more information? – user113716 Feb 09 '11 at 18:42
  • Solved it thank to patrick_dw's request for more info. I'm pulling the data from the page and storing it in an Object using jQuery and I use another function to do it and in there I was using parseInt on the hours, so the were being converted before they even got to the function I was in. In trying to explain the process I had to walk myself back to stuff I did a few weeks ago. Thanks! : D – PruitIgoe Feb 09 '11 at 19:01

4 Answers4

3

I think you must have some other problem, as what you are describing should work. For example (here's a bad-but-direct translation of your code):

var grid = [ ".5", ".25", "1.25", "3.75" ];
var th = 0;
for (x in grid){
  var h = grid[x];
  var hrs = parseFloat(h);
  th = th + hrs;
  console.log( h, hrs );
}
//   .5 0.5
//  .25 0.25
// 1.25 1.25
// 3.75 3.75

console.log( th );
// 5.75

A few things you should change about your code anyhow:

  1. Don't use for ( x in a ) to iterate over an array; use a numeric for loop: for (var i=0,len=a.length;i<len;++i)

  2. Always var your variables. You're using and overwriting a global thisrow variable. Even when you use for ... in, do it like so for (var x in o) (unless you have declared your variable earlier in the function).

  3. You should use th += ... instead of th = th + ..., just because it's shorter and DRYer.

  4. You should use *1 instead of parseFloat. It's faster, less typing, and doesn't lie to you when you have a janky string.

Community
  • 1
  • 1
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • thanks for the code tips. 1 - it's an object or associative array, I mistyped above. 2 - doh, I usually do as you say, not sure why I didn't here. 3. Another doh. 4. Didn't know that, +1 tip there, but janky? : D – PruitIgoe Feb 09 '11 at 19:04
2
var hours = objGrid[thisrow]['hours']+"";

should do the trick. ParseFloat() takes charaster number's value.

Thevs
  • 3,189
  • 2
  • 20
  • 32
  • Could you please explain this answer? I fail to understand what you mean, or how it helped. Why is this the accepted answer? – Phrogz Feb 09 '11 at 19:12
  • I had accepted yours, must of accidentally clicked on this one after. I've corrected it. – PruitIgoe Feb 09 '11 at 19:23
0

The question is: why are your decimal values being rounded. After poking around myself, I found that the for(... in ...) construct itself is rounding the values down. If you access the array element directly, i.e. objGrid[0][i], then the floats will retain their original value, and not be rounded. Hence, my suggestions would be to use a standard for() loop instead of for(in).

EDIT:

For those disbelieving my results, check out this code snippet:

var arr = [.5,.25,1.25, 3.75];

alert(arr[0]);

for(v in arr){
    alert(arr[0]);
    alert(v);
}

This is way simplified version of the OP's question, but same principle. Look at the results of the alert statements. It will be .5, .5, then 0 ... all from how I'm referencing the variable, which is presumably pointing to the same place in memory, but in the later case, rounding the value (apparently).

Tested this myself on the latest version of Firefox.

user470714
  • 2,858
  • 1
  • 28
  • 34
  • *"the for(... in ...) construct itself is rounding the values down"* Huh? You sure you're not using the property indices instead of the values? – user113716 Feb 09 '11 at 18:46
  • @user47014 I find that hard to believe; can you share reproducible results of your poking around? – Phrogz Feb 09 '11 at 18:47
  • That was not happening - see my last reply to patrick_dw above. – PruitIgoe Feb 09 '11 at 19:02
-1

Not sure about this, but try to write var th = 0.0; - maybe, javascript recognizes first integer number and tries to convert second operant to integer. By the way, what browser do you use?

Paul Lysak
  • 1,284
  • 1
  • 14
  • 18
  • 2
    JavaScript does not differentiate Integers or Floats. – Phrogz Feb 09 '11 at 18:26
  • @Phrogz - then why parseInt and parseFloat? Why not parseNumber or something universal if there's no difference? – PruitIgoe Feb 09 '11 at 18:40
  • @Pruitgoe The same reason there is `Math.round/floor/ceil`: sometimes you have a non-integer number and you want to find a nearby integer. `parseInt("3.1")==3.0 // true` – Phrogz Feb 09 '11 at 18:46
  • right, but what if you have a string (which I have in this case) that is representing a decimal/float and you need to convert to a actual decimal or float - say str = 5.4 wouldn't parseInt(str) = 5.0 whereas parseFloat(str) = 5.5? – PruitIgoe Feb 09 '11 at 19:06