0

I have a "class" called Block. It possesses three variables : x, y, and z, which are its three-dimensional coordinates, respectively. I am having trouble finding the number of "neighbours" to a block. That is, if this shares a face, edge, or vertex with other, it should return true. So, block.neighbours() returns the number of neighbours to block. However, it is returning 0 rather than the expected 1. My code is shown below:

var blocks = [];

  function Block(x, y, z) {
    blocks.push(this);
    this.x = x;
    this.y = y;
    this.z = z;
    this.neighbours = function() {
      var n = 0;
      for (var block in blocks) {
        if (block == this) {
          continue;
        }
        if (Math.abs(block.x - this.x) <= 1 && Math.abs(block.y - this.y) <= 1 && Math.abs(block.z - this.z) <= 1) {
          n++;
        }
      }
      return n;
    };
  }

  var b1 = new Block(0, 0, 0);
  var b2 = new Block(0, 1, 0);
  document.getElementById("box").innerHTML = b1.neighbours();

Why is the function returning 0? (Note: Before the javascript I have the html <p id = "box"></p>, and in the paragraph it shows 0).

hyper-neutrino
  • 5,272
  • 2
  • 29
  • 50

3 Answers3

0

The bug in your code is that for (var block in blocks) { is not iterating as you expect -- var block in blocks iterates over the property names which are 0 and 1 as demonstrated here:

http://jsfiddle.net/yxzobjhb/

You could fix it by doing this:

    for (var blockKey in blocks) {
        var block = blocks[blockKey];

JSFiddle: http://jsfiddle.net/yxzobjhb/2/

Another way to fix it would be to write it like this:

var blocks = [];

function Block(x, y, z) {
    blocks.push(this);
    this.x = x;
    this.y = y;
    this.z = z;
    this.neighbours = function() {
        var n = 0;
        blocks.forEach(function(block) {
            if (block != this && Math.abs(block.x - this.x) <= 1 && Math.abs(block.y - this.y) <= 1 && Math.abs(block.z - this.z) <= 1) {
                n++;
            }
        }, this);
        return n;
    };
}

var b1 = new Block(0, 0, 0);
var b2 = new Block(0, 1, 0);
document.getElementById("box").innerHTML = b1.neighbours();

JSFiddle: http://jsfiddle.net/jLxw316c/2/

Cymen
  • 14,079
  • 4
  • 52
  • 72
0

The for ... in statement returns keys, not the actual values of a map/array. You'd have to look up the block within each iteration, e.g.

var key, block;
for (key in blocks) {
    block = blocks[key]
    /* ... */
}
Denis 'Alpheus' Cahuk
  • 4,152
  • 2
  • 23
  • 31
0

You shouldn't use for...in with arrays. However, if you do, it gets the property names, not the values. You would have to do this:

for (var index in blocks) {
    var block = blocks[index];

In your existing code, block is 0 the first iteration and 1 the second.

However, you should use this:

for(var i = 0; i < blocks.length; i++){
    var block = blocks[i];
Community
  • 1
  • 1
James Montagne
  • 77,516
  • 14
  • 110
  • 130