Reputation: 1764
I have a function (getCoeff()
) which returns one-dimensional arrays. I try to use it to fill a two-dimensional array:
//set up an 3x3 array for A
A = new Array(3);
for (var i=0; i<3; i++) {
A[i] = new Array(3);
}
//fill it per row using getCoeff()
for (var i=0; i<3; i++) {
A[i] = getCoeff(i+1);
}
console.log(A);
console.log(getCoeff(1));
console.log(getCoeff(2));
console.log(getCoeff(3));
but I only get the first row filled and the other two remain empty:
[ [ -3, 2, -1 ], [ , , ], [ , , ] ]
[ -3, 2, -1 ]
[ 2, -3, 2 ]
[ 1, -1, 3 ]
As you can see the function returns the rows correctly but for some reason It doesnt work inside the loop.
On the other hand if I try something like this:
for (var i=0; i<3; i++) {
A[i] = [1,2,3];
}
console.log(A);
it works fine!
[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
What's wrong with my code?!
Update:
My original full code before the edits:
var fs = require('fs');
var input = "LPinput.txt";
var c = new Array();
var A = new Array();
var b = new Array();
var Eqin = new Array();
var MinMax;
open(input);
console.log(c);
console.log(A);
console.log(b);
console.log(Eqin);
console.log(MinMax);
function open(filename) {
if (fs.existsSync(filename)) {
var data = fs.readFileSync(filename).toString().split("\n");
analyse(data);
} else {
console.log("ERROR: File doesnt exist!");
}
}
function analyse(data) {
//clean up whitespaces
for (i in data) {
data[i] = data[i].replace(/\s/g, '');
}
//check LP type & clean up
if (data[0].substring(0,3) == "max") {
MinMax = 1;
data[0] = data[0].replace("max","");
} else if (data[0].substring(0,3) == "min") {
MinMax = -1;
data[0] = data[0].replace("min","");
} else {
console.log("ERROR: Invalid format!");
return;
}
//check constraints format & clean up
if ( data[1].substring(0,4) != "s.t.") {
console.log("ERROR: Invalid format!");
return;
} else {
data[1] = data[1].replace("s.t.","");
}
//get variables
var variables = data[data.length-1].split(",");
var last = variables[variables.length-1];
variables[variables.length-1] = last.substring(0,last.indexOf(">"));
//get number of constraints
var constraints = data.length-2;
c = getCoeff(0);
//===============================
//I JUST NEED TO POPULATE A TO FINISH THIS
for (var i=0; i<constraints; i++) {
A[i] = getCoeff(i+1);
}
//===============================
for (var i=1; i<data.length-1; i++) {
var end = data[i].length;
var start = end;
while (data[i].charAt(start) != "=") {
start = start - 1;
}
b[i-1] = parseInt(data[i].substring(start+1,end));
if (data[i].charAt(start-1) == "<") {
Eqin[i-1]=-1;
} else if (data[i].charAt(start-1) == ">") {
Eqin[i-1]=1;
} else {
Eqin[i-1]=0;
}
}
function getCoeff(row) {
var coeff = new Array();
for (i in variables) {
var pos = data[row].indexOf(variables[i]);
if ((data[row].charAt(pos-1) == "+") || (pos-1 < 0)) {
coeff[i]=1;
} else if (data[row].charAt(pos-1) == "-") {
coeff[i]=-1;
} else if (data[row].charAt(pos-1) == "*") {
var end = pos-1;
var start = end;
while ( (start > -1) && (data[row].charAt(start) != "+") && (data[row].charAt(start) != "-") ) {
start = start - 1;
}
coeff[i] = parseInt((data[row].substring(start,end)));
}
}
return coeff;
}
}
LPinput.txt:
max 2*x1+x2-4*x3-15
s.t.-3*x1+2*x2-x3>=5
2*x1-3*x2+2*x3<=9
x1-x2+3*x3<=5
x1,x2,x3>=0
Update #2:
Console output:
[ 2, 1, -4 ]
[ [ -3, 2, -1 ] ]
[ 5, 9, 5 ]
[ 1, -1, -1 ]
1
It should be:
[ 2, 1, -4 ]
[ [ -3, 2, -1 ],[ 2, -3, 2 ],[ 1, -1, 3 ]]
[ 5, 9, 5 ]
[ 1, -1, -1 ]
1
Upvotes: 0
Views: 254
Reputation: 2068
Here is the real problem:
you are using an i
variable in your outer scope.
for (var i=0; i<constraints; i++) {
A[i] = getCoeff(i+1);
}
When you go inside the getCoef
you have this for loop
for (i in variables) {
and since you have not declared the i
here, it uses the same i
declared in the outer scope. After the first run of the for loop (which fills the first row of A), i
is changed to "0"
as opposed to the numeric value 0. Therefore the condition of the for
loop is no longer valid and it exits the loop.
There you go!
Upvotes: 1
Reputation: 147363
In your code:
A = new Array(3);
you should declare varaibles, and initialising an array with a length is usually unnecessary. Also, variables starting with a capital letter are, by convention, reserved for construtors (though some use variable names in all capitals to represent constants).
Consider using an array initialiser:
var a = [];
for (var i=0; i<3; i++) {
Initialising arrays in the following loop is a bit useless as you replace them in the next loop:
a[i] = [];
}
In the next loop, i is needlessly declared again (there is no block scope in javascript). It is common to use a different variable in these cases (though re-using i has no ill effects, it's just not liked):
for (var j=0; j<3; j++) {
a[j] = getCoeff(j + 1);
}
So creating a getCoeff function that just returns an array of the value passed to it (purely for testing):
function getCoeff(v){
return [v,v,v];
}
"works":
console.log(a.join(' - ')); // 1,1,1 - 2,2,2 - 3,3,3
Upvotes: 0
Reputation: 1200
In my case, I got last 2 populated. Anyways, if you run loop from 0, you better write
A[i] = getCoeff(i+1);
OR
you run that loop starting from 1 to less than equals 3.
Upvotes: 0