Jump to content
cklymowsky

HELP with nested "for" "do" loop

Recommended Posts

HI All, 

 

I can't figure out how to solve this nested for do loop to get it to work. I'm getting the following error despite defining my variable at the start.

 

Excerpt from rpt file with error message:

17:01:59 File functions\SetUp\fn_createMarkers.sqf [BEAKS_fnc_createMarkers], line 18
17:01:59 Error in expression <sectorPairArray pushBack [_firstSector, |#|_otherSector]; 
};
_i = _i +1;
};
para>
17:01:59   Error position: <_otherSector]; 
};
_i = _i +1;
};
para>
17:01:59   Error Undefined variable in expression: _othersector

My script with the nested "for" "do" loop contains the following:

params ["_firstSector","_otherSector","_sectorPairArray"];

// get unique pairs of sectors
_firstSector = objNull;
_otherSector = objNull;
_sectorPairArray = [];
__I = 0;
hint format ["allSectorsArray: \n %1", allSectorsArray];

for "_i" from 0 to (count allSectorsArray - 1) do {
	_firstSector = allSectorsArray select _i;
	_i = __I;
	for "_i" from __I to (count allSectorsArray - 1) do {
		_i = _i +1;
		_otherSector = allSectorsArray select _i;
		_sectorPairArray pushBack [_firstSector, _otherSector]; 
	};
	_i = _i +1;
};

allSectorsArray is a global variable array of sectors.

 

Share this post


Link to post
Share on other sites

How are you calling your script?

Share this post


Link to post
Share on other sites
7 minutes ago, xjoker_ said:

wow so many questions 

 

t0P9WMDPRI_o6MKYfEwRkQ.png

 

 

All of that, too!

Share this post


Link to post
Share on other sites

Not sure what is wrong with "_i"  in   for "_i" from __I to (count allSectorsArray - 1) do {   as it is used as the VARNAME in the example of Control Structures: https://community.bistudio.com/wiki/Control_Structures#for-from-to-Loop

 

I am setting _i equal to __I  (another variable) that gets it value every time it goes through the outer loop and using it as the STARTVALUE  in the inner loop.

 

I fixed the +1 to + 1.

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
3 hours ago, Harzach said:

How are you calling your script?

 

I asked this for a reason. Assuming you are using params correctly, you then immediately delete your input arguments.

 

params ["_firstSector","_otherSector","_sectorPairArray"]; //parses input arguments

//delete arguments
_firstSector = objNull;
_otherSector = objNull;
_sectorPairArray = [];

 

Share this post


Link to post
Share on other sites
37 minutes ago, Harzach said:

 

I asked this for a reason. Assuming you are using params correctly, you then immediately delete your input arguments.

 

 

 

Thanks Harzach,

Not sure if I was using params correctly, I though you could use it similar to private, but in this case I wasn't calling in a variable. I set otherSector = objNull; to define it, thinking this was the problem.

 

Instead I found the issue and it does what I want it to do with the following:

 

Quote

private ["_firstSector","_otherSector","_sectorPairArray"];

// get unique pairs of sectors
_firstSector = objNull;
_otherSector = objNull;
_sectorPairArray = [];
 

for "_i" from 0 to (count allSectorsArray - 1) do {
 _firstSector = allSectorsArray select _i;
 __I = _i+1;
 for "_j" from __I to (count allSectorsArray - 1) do {
  _otherSector = allSectorsArray select _j;
  _sectorPairArray pushBack [_firstSector, _otherSector];
 };
};

 

Share this post


Link to post
Share on other sites
2 hours ago, cklymowsky said:

Not sure what is wrong with "_i"  in   for "_i" from __I to (count allSectorsArray - 1) do {   as it is used as the VARNAME in the example of Control Structures: https://community.bistudio.com/wiki/Control_Structures#for-from-to-Loop

 

I am setting _i equal to __I  (another variable) that gets it value every time it goes through the outer loop and using it as the STARTVALUE  in the inner loop.

 

I fixed the +1 to + 1.

 

 

Changing the iterator from inside a for loop is bad practice and most likely an indicator that you don't need a for loop in the first place.

When you need to nest a for loop, readability dictates to increase the letter of the iterator like this:

for "_i" from 0 to 10 do {
	for "_j" from 0 to 5 do {
		for "_k" from 0 to 2 do {

		};
	};
};

This way it's always crystal clear in which scope inside the nested loops you are.

Using double underscore prefixes can open a can of worms, especially if you want others to check your stuff, I easily missed the double underscore in front of I at first glance.

 

In your case you increase the outer iterator after every nested loop, which should effectively lock up the game.

Care to elaborate what you're actually trying to achieve here?

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

OK, I think I understand what you are trying to do. And for the record, explaining clearly and concisely what you are trying to do is an important step when seeking guidance from others.

 

You have an array (allSectorsArray) that you want to rebuild into an array of pairs:

allSectorsArray = [0,1,2,3,4,5,6,7];
_sectorPairArray = allSectorsArray call BIS_fnc_magicHappens;
//_sectorPairArray returns [[0,1],[2,3],[4,5],[6,7]];

You might try something more along the lines of this:

private ["_firstSector","_otherSector","_sectorPairArray"];

_firstSector = objNull;
_otherSector = objNull;
_sectorPairArray = [];

hint format ["allSectorsArray: \n %1", allSectorsArray];

for "_i" from 0 to (count allSectorsArray - 1) step 2 do {

	_firstSector = allSectorsArray select _i;
	_otherSector = allSectorsArray select _i + 1;
	_sectorPairArray pushBack [_firstSector, _otherSector]; 

};

 

Share this post


Link to post
Share on other sites

 

Thanks both to Grump and Harzach, appreciate the ongoing support and patience. Your feedback did help!

 

Now finally got it working with:

 

allSectorsArray = [0,1,2,3,4,];

for "_i" from 0 to (count allSectorsArray - 1) do {
	_firstSector = allSectorsArray select _i;
	__I = _i+1;
	for "_j" from __I to (count allSectorsArray - 1) do {
		_otherSector = allSectorsArray select _j;
		_sectorPairArray pushBack [_firstSector, _otherSector]; 
	};
};

//_sectorPairArray returns [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]

 

Not sure it there was better way to do this?

Share this post


Link to post
Share on other sites

Ah, so you want an array with all possible non-repeating pairs? It seems there is always a "better" way to do things, but if that's working for you then I'd say mission accomplished. Definitely take heed of Grumpy Old Man's advice, though. The double underscore thing can cause problems, so consider using something different. Remember, a variable can be pretty much anything. Descriptive variables are best IMO.

Share this post


Link to post
Share on other sites
41 minutes ago, cklymowsky said:

//_sectorPairArray returns [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]

 

Not sure it there was better way to do this?

 

A few, actually, depends on what you want to return:

//0.0297ms:
allSectorsArray = [0,1,2,3,4];
_sectorPairArray = [];
allSectorsArray apply {
	_element = _x;
	(allSectorsArray - [_element]) apply {
		_sectorPairArray pushBack [_element,_x]
	}
};
//returns pairs where the first element can't also be the second element:
//[[0,1],[0,2],[0,3],[0,4],[1,0],[1,2],[1,3],[1,4],[2,0],[2,1],[2,3],[2,4],[3,0],[3,1],[3,2],[3,4],[4,0],[4,1],[4,2],[4,3]]



//0.0294ms:
allSectorsArray = [0,1,2,3,4];
_sectorPairArray = [];
allSectorsArray apply {
	_element = _x;
	allSectorsArray apply {
		_sectorPairArray pushBack [_element,_x]
	}
};
//returns all possible pairs:
[[0,0],[0,1],[0,2],[0,3],[0,4],[1,0],[1,1],[1,2],[1,3],[1,4],[2,0],[2,1],[2,2],[2,3],[2,4],[3,0],[3,1],[3,2],[3,3],[3,4],[4,0],[4,1],[4,2],[4,3],[4,4]]

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
3 minutes ago, Grumpy Old Man said:

A few, actually:

I think he just wants non-repeating pairs, though. For example, [0,4] and [4,0] will be functionally identical.

  • Like 1

Share this post


Link to post
Share on other sites
11 hours ago, Harzach said:

I think he just wants non-repeating pairs, though. For example, [0,4] and [4,0] will be functionally identical.

allSectorsArray = [0,1,2,3,4];
sectorPairArray = [];
{
	_element = _x;
	{
		sectorPairArray pushBack[ _element, _x ];
	}forEach ( allSectorsArray select[ _forEachIndex + 1, count allSectorsArray ] );
}forEach ( allSectorsArray select[ 0, count allSectorsArray - 1 ] );
sectorPairArray
  
//[[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]

 

  • Like 3

Share this post


Link to post
Share on other sites

OK thanks Larrow,

 

Yours is 0.0179ms and my for do loop is 0.0.0274ms.

 

Thanks again!

 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×