Home > Back-end >  Using a for loop to update with a class method - not working
Using a for loop to update with a class method - not working

Time:04-30

I'm trying to create an array of objects with a "Node" class constructor. Each Node should have an array containing neighbouring nodes. When I use a for loop to iterate through each Node to add neighbours, it triggers the class method, but the Node object fails to update.

Here's a contrived/simplified version of what I'm doing:

export default class Node {
    neighbours: Node[];
    addNeighbours: (thisNode: Node) => void;
    constructor() {
        this.neighbours = [];
        this.addNeighbours = function (thisNode: Node) {
            thisNode.neighbours = []
            this.neighbours.push(thisNode)
            console.log(this.neighbours.length); // returns 1. So this is being triggered and appears to be working.
        }
    }
}

// Create an array to represent the 2D grid.
export function createArrayOfNodes(): Node[][] {
    let returnGrid: Node[][] = [
        [new Node(), new Node(), new Node()],
        [new Node(), new Node(), new Node()],
        [new Node(), new Node(), new Node()],
    ]

    // add neighbours to each Node
    for (let i = 0; i < returnGrid.length; i  ) {
        for (let j = 0; j < returnGrid.length; j  ) {
            const newJ = j   1 === returnGrid.length ? 0 : j   1
            returnGrid[i][j].addNeighbours(returnGrid[i][newJ]); // This fails to add a neighbour
            // returnGrid[i][j].addNeighbours(new Node()); // This adds a neighbour OK
        }
    }
    // returnGrid[0][0].addNeighbours(returnGrid[0][1]); // This adds a neighbour OK

    return returnGrid;
}

console.log(createArrayOfNodes) // Returns an array of Nodes, but they don't have any Nodes in their neighbour properties.

As per the commented out code, I can update the neighbours property if it's outside the for loop. If I'm inside the for loop I can update the neighbours property if I create a new Node, but not if I try to add a Node from the returnGrid. Can anyone please explain this?

CodePudding user response:

Seems the following line made your code not work. Commented it out all works fine.

thisNode.neighbours = [];

Node should look like below

export default class Node {
  neighbours: Node[];
  addNeighbours: (thisNode: Node) => void;
  constructor() {
    this.neighbours = [];
    this.addNeighbours = function (thisNode: Node) {
      this.neighbours.push(thisNode);
    };
  }
}

Actually, you could have defined the addNeighbours outside the constructor.

export default class Node {
  neighbours: Node[];

  constructor() {
    this.neighbours = [];
  }

  addNeighbours = function (thisNode: Node) {
    this.neighbours.push(thisNode);
  };
}

Working example,

Edit TypeScript (forked)

CodePudding user response:

Everytime you call the addNeighbours method you reassign the neighbours array of the passed Node. This will effectively reset the neighbours array of that passed Node.

Remove the thisNode.neighbours = [] line.

class Node {
  neighbours = [];

  addNeighbours(thisNode) {
    this.neighbours.push(thisNode)
  }
}

// Create an array to represent the 2D grid.
function createArrayOfNodes() {
  let returnGrid = [
    [new Node(), new Node(), new Node()],
    [new Node(), new Node(), new Node()],
    [new Node(), new Node(), new Node()],
  ]

  // add neighbours to each Node
  for (let i = 0; i < returnGrid.length; i  ) {
    for (let j = 0; j < returnGrid.length; j  ) {
      const newJ = j   1 === returnGrid.length ? 0 : j   1
      returnGrid[i][j].addNeighbours(returnGrid[i][newJ]);
    }
  }

  return returnGrid;
}

console.log(createArrayOfNodes());

Sidenote: I noticed how you declared your properties and methods on your Node class. You're allowed to assign properties and methods that every instance should inherit inside of the class scope, instead of the constructor.

The constructor can be used to assert logic and process arguments when instantiating classes.

export default class Node {
  neighbours: Node[] = [];

  addNeighbours(thisNode: Node): void {
    this.neighbours.push(thisNode)
  }
}
  • Related