The Pro Hands The Pro Hands - 3 months ago 10
Javascript Question

My function doesn't not return object in a for loop

I created a function which takes the inner of the tag

S
in a XML string:

'<C><P /><Z><S>[Grounds here]</S><D /><O /></Z></C>'


, containing grounds data, obviously related to a game. Then I consume every ground data in this inner until I reach the number
z
with
i
in my
for
loop and return the data of the first/one remaining ground as a object.

The problem is the function returns
undefined
instead of a
object
.




This is the function:

/**
* Get a string between 2 strings.
*/
String.prototype.between = function(left, right) {
var sub = this.substr(this.lastIndexOf(left) + left.length);
return sub.substr(0, sub.indexOf(right));
}

/**
* @param number z The inner position of the ground I want to read, e.g, 1, the first.
*/
function readGround(z) {

// string containing all existent grounds
var groundsData = xml.substr(STG.indexOf('<S>') + 3, STG.lastIndexOf('</S>'));

// Iterate the grounds while z isn't reached
for(var i = 1; i < z; i++) {

// Get the ground inner
var outer = groundsData.substr(groundsData.indexOf('<S') + 3, groundsData.indexOf('/>'));

// Check if i reached z
if(i === z) {

// Get grounds properties
var a = [
outer.between('L="', '"'),
outer.between('H="', '"'),
outer.between('X="', '"'),
outer.between('Y="', '"')
];

return {
L: a[0], H: a[1],
X: a[2], Y: a[3]
};

// Else skip this ground
} else groundsData = groundsData.substr(groundsData.indexOf('/>'), groundsData.length);
}
}

Answer

Your loop makes i go from 1 to num-1. But within the loop you have a condition if(i==num). This condition is never true, so the programme never reaches the return statement. If the programme flow inside a function means that no return statement is ever reached, then the function simply returns undefined. (This isn't javascript-specific - similar rules apply in many languages.)

Instead, you can move the return statement outside of the loop.

function readGround(num) {
    var grounds = stg.substr(stg.indexOf('<S>') + 3, stg.lastIndexOf('</S>')),
        gr;
    for (var i = 1; i < num; i++) {
        grounds = grounds.substr(grounds.indexOf('/>') + 2, grounds.length);
    }
    gr = grounds.substr(grounds.indexOf('<S') + 3, grounds.indexOf('/>'));
    var a = [stringBetween(gr, 'L="', '"'), stringBetween(gr, 'H="', '"'), stringBetween(gr, 'X="', '"'), stringBetween(gr, 'Y="', '"')];
    return {
        L: a[0],
        H: a[1],
        X: a[2],
        Y: a[3]
    };
}

(A few other things also had to be tweaked to make your code work, such as that a should read from the section of text in gr rather than from the longer string grounds)

jsfiddle

Comments