Javascript: console.log(arr.length) says length is n, console.log(arr) says length is n-1. Second case won't show last element

StackOverflow https://stackoverflow.com/questions/23455722

Question

The first line will print, say, 10, while the second will print 1 less:

console.log("ds length: " + ds.length);  // Prints, say, 10
console.log(ds); // Prints all but last element and says length is one less.

Some relevant parts of my code, all in the singleton AS:

FindPath: function(oX, oY, dX, dY) { // origin, destination
        var heap = AS.Heap();

        var g = AS.Grid; // AS.Grid is declared, in AS, as: Grid: new Array(),

        var node;

        var cn = g[oX][oY]; // current node
        var dn = g[dX][dY]; // destination node

        heap.push(cn);

        cn.CoorType = AS.CoorType.VISITED;

        while (heap.length > 0) {
            cn = heap.pop();

            if (cn === dn) {
                var ds = new Array(); // direction set (instructions)
                var pn;// parent node;

                do {
                    pn = cn.Parent;
                    ds.push({
                        Dir: cn.Y - pn.Y !== 0 ? cn.Y - pn.Y < 0 ? AS.Direction.UP : AS.Direction.DOWN : cn.X - pn.X > 0 ? AS.Direction.RIGHT : AS.Direction.LEFT,
                        Node: cn});
                    cn = pn;
                } while (pn.Parent);

                console.log("ds length: " + ds.length);
                console.log(ds);

                AS.CleanUp();
                return ds;
            }

                    // Bellow, I'm not using functions 'cause occasionally, when FindPath() is called multiple times in a large area within a few milliseconds, it will get laggy. I removed the use of functions to increase performance.
            node = g[cn.X+1][cn.Y];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X][cn.Y+1];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X-1][cn.Y];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X][cn.Y-1];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
        }

        AS.CleanUp();
        return heap; // No path found
    },

Heap: function() {
    var heap = new Array();

    heap.Sink = function(node) {
        var i = this.length-1;

        while (i > 0 && this[i].Score < node.Score) i--;

        this.splice(i, 0, node);
    };

    return heap;
},

CleanUp: function() { // Cleans up changes made by any previous path search
    var x, y, g = AS.Grid;

    var limX = g.length - 3;
    var limY = g[0].length - 3;

    for (x = 2; x < limX; x++) {
        for (y = 2; y < limY; y++) {
            if (g[x][y].CoorType === AS.CoorType.VISITED) {
                g[x][y].CoorType = AS.CoorType.NOTHING;
                delete g[x][y].Parent;
            }
        }
    }
}

I realised that sometimes, my objects that are supposed to move according to the path returned by FindPath will miss one step. Then I saw what I described above.

enter image description here

Was it helpful?

Solution

By adding two lines in the do {} while (pn.Parent):

do {
    pn = cn.Parent;
    ds.push({
        Dir: cn.Y - pn.Y !== 0 ? cn.Y - pn.Y < 0 ? AS.Direction.UP : AS.Direction.DOWN : cn.X - pn.X > 0 ? AS.Direction.RIGHT : AS.Direction.LEFT,
        Node: cn});
    console.log(ds.length); // Added this line,
    console.log(ds);        // and this one
    cn = pn;
} while (pn.Parent);

I realised that the console.log(ds) was printing ds as it was after a call to GameLoop() which would call, at some point, AS.FindPAth, while console.log(ds.length) was printing ds.length as it was at the time I asked it be printed.

Since, before the end of GameLoop(), I was removing the last element of the path returned my FindPath() (nextDirection = path.pop()), console.log(ds) would print itself missing one element.

Still, javascript makes one go nut when it does things like printing the state of an object as it will be later rather than as it is at the time of the console.log()...

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