0

I have a loop that generates a random number between 0 and 5 and goes fetch a color in an array.

The first color is always yellow and I cannot figure out why.

var hexColors = new Array("#000000", "#FFFFFF", "#FF0000", "#0000FF", "#00FF00", "#FFFF00");
var nameColors = new Array("White", "Red", "Blue", "Black", "Green", "Yellow");

for (var i = 5; i >= 0; i--) {
  var hexColor = randomNum(i);
  var nameColor = randomNum(i);
  $('td:eq(' + i + ')').css("color", hexColors[hexColor]);
  $('td:eq(' + i + ')').html(nameColors[nameColor]);
  hexColors.splice($.inArray(hexColors[hexColor], hexColors), 1);
  nameColors.splice($.inArray(nameColors[nameColor], nameColors), 1);
}

function randomNum(max) {
  return Math.floor(Math.random() * max);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>

I re-factored the loop so that it uses increments instead of i-- and it works but I'd still like to know why it doesn't work the other way around.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
gyc
  • 4,300
  • 5
  • 32
  • 54

3 Answers3

0

Your function randomNum(max) will return a maximum value of max-1, so 4 ! (not 5)

That's because Math.random() actually returns a float number between 0 and 1 EXCLUDING 1 !!!

This one works :

function randomNum(max) {
    return Math.floor(Math.random() * (max+1));
}
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). In the meantime, please do not use answers to post comments. – elixenide Nov 30 '14 at 22:20
  • So I have the good answer but I can't give it since you don't like to read comments in answers ? Cool... btw, my answer isn't really a "comment".. – Alexandre Dees Nov 30 '14 at 22:32
  • It wasn't an answer, until you edited it. It was just a comment on mrahmat's answer, which is okay in the comments, but not okay as an answer. – elixenide Nov 30 '14 at 23:43
  • Nope.. what I wrote was about the original function, not about mrahamat answer. I just began my answer saying that mrahmat's one was wrong (which wasn't very fairplay ok..). – Alexandre Dees Dec 01 '14 at 10:37
0

"Yellow" is always first because randomNum is returning a number between 0 and i, but i in your case is between 0 and 5. Floor rounding causes i to be between 0 and 4. In result, you get last element in both arrays yellow due to the splicing. That's why yellow is always first.

That's can be solved by adding 1 to i as argument to randomNum.

for (var i = 5; i >= 0; i--) {
  var hexColor = randomNum(i+1);
  var nameColor = randomNum(i+1);

  /* ... */
}

http://jsfiddle.net/volter9/2d3k4p7n/

I hope that's explains why it's yellow and solves your problem.

P.S.: new Array is slower than [] (array literal) source.

Community
  • 1
  • 1
volter9
  • 737
  • 5
  • 16
0

Alexandre Dees’ answer is correct, I will give you the details:

  1. randomNum will give you only random integers from 0 up to, but not including max. This is because Math.random() returns a number between 0 up to, but not including 1. Even if it would, the probability to get 1 would be so small, that most probably you’d still get yellow as color on the first item every time.

  2. Your array(s) of colors have six items each. On the first five iterations you will always get one of the first items, since your random numbers are always produced with randomNum(array.length - 1) – The number of elements in these arrays decreases by one on every iteration, just like the iteration variable.

  3. In the very last iteration step your arrays only contain one element: '#ffff00' and 'Yellow', respectively. i is 0, and 0 * Math.random() is 0. Therefore, only now the values for yellow can be accessed.

  4. Is it possible that when using forward iteration, it is always the last table cell ending up yellow? ;-)

David Aurelio
  • 484
  • 2
  • 11