Question

In this JSBIN demo, you will see the following code:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script>
 function createPallet(){
    R = Array('00', '33', '66', '99', 'CC', 'FF');
    G = Array('00', '33', '66', '99', 'CC', 'FF');
    B = Array('00', '33', '66', '99', 'CC', 'FF');
    pallet = [];
    j = 0;
    for (x = 0; x < R.length; x++){
      for (y = 0; y < G.length; y++){       
        for (z = 0; z < B.length; z++){
          pallet[j] = "#"+R[x]+G[y]+B[z];
          j++;          
        }
         pallet[j] = "#"+R[x]+G[y]+B[z];
        j++;

      }
      pallet[j] = "#"+R[x]+G[y]+B[z];
        j++;
    }
   return pallet;
 }   
  </script>
</head>
<body>
  <select style="width: 150px">
<script>
  pallet = createPallet();
  alert("Number of colors: "+pallet.length)
  for (i = 0; i < pallet.length; i++){
    document.write("<option style='background-color:"+pallet[i]+"' title='"+pallet[i]+"'>&nbsp;</option>");

  }

  </script>
  </select>
</body>
</html>

I have got 258 colors, However there are repeated undefined blue values B in the list shown in white option's title. I believe that it is because something wrong in the nested loops, I could not able to figure out it. Another thing, I expect it to return 256 colors not 258! How could I solve this issue?

Was it helpful?

Solution

I think only the inner-most loop needs the push:

for (x = 0; x < R.length; x++){
    for (y = 0; y < G.length; y++){       
        for (z = 0; z < B.length; z++){
            pallet[j] = "#"+R[x]+G[y]+B[z];
            j++;          
        }
    }
}

OR

for (x = 0; x < R.length; x++){
    for (y = 0; y < G.length; y++){       
        for (z = 0; z < B.length; z++){
            pallet.push("#"+R[x]+G[y]+B[z]);
        }
    }
}

The count should be 216. 6*6*6 = 216. The undefined values were in there because the loop variable, z for instance, gets incremented the last time it exits the loop. So after the loop was complete, you were referencing the variable at which point the value would be 1 more than the length of the array, resulting in the undefined value.

update To clarify

for (x = 0; x < R.length; x++){
    for (y = 0; y < G.length; y++){       
        for (z = 0; z < B.length; z++){
            pallet[j] = "#"+R[x]+G[y]+B[z];
            j++;          
        }
        //remove ==> pallet[j] = "#"+R[x]+G[y]+B[z];
        //remove ==> j++;          
    }
    //remove ==> pallet[j] = "#"+R[x]+G[y]+B[z];
    //remove ==> j++;          
}

OTHER TIPS

This is much cleaner when done with JavaScript's array object's forEach method.

Use this as your createPallet function instead:

function createPallet(){
    var R = Array('00', '33', '66', '99', 'CC', 'FF');
    var G = Array('00', '33', '66', '99', 'CC', 'FF');
    var B = Array('00', '33', '66', '99', 'CC', 'FF');
    var pallet = [];
    R.forEach(function(r) {
        G.forEach(function(g) {
            B.forEach(function(b) {
                pallet.push("#"+r+g+b);
            });
        });
   });
   return pallet;
} 

Also note that this correctly returns an array of 216 colours not 256 because you have 6 elements in the R, G and B arrays and 6 * 6 * 6 == 216. See: http://www.helensimages.com/hexcolor.htm

Remember to acknowledge that arrays start from 0 while length will give you the actual length of an array ie.

R.length // G.length // B.length all equal 6

when the array values start from [0-5]

So for your loops you will need to use

for (x = 0; x < R.length-1; x++){}

..and this applies to all your loops

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top