Jump to content
Sign in to follow this  
iceman77

Accessing elements of an array effeciently

Recommended Posts

_someArray = ["class_name1","class_name2","class_name3","class_name4","class_name5"];
_randomStuff = _someArray select (floor(random(count _someArray)));

if ((_randomStuff == _someArray select 0) || (_randomStuff == _someArray select 1) || (_randomStuff == _someArray select 2))  then { ...do some shit... }

How can I access the first 3 elements of the array without such a long condition? Is there a better way?

Edited by Iceman77

Share this post


Link to post
Share on other sites

While that is ok the way you have it written. Its best not to design your code where you have to compare strings. Comparing strings is a lot more system intensive.

I would try to think up a totally different way of getting the same effect so you can avoid that type of coding. Is this just a thought experiment, or you trying to do something specific?

---------- Post added at 09:05 PM ---------- Previous post was at 08:59 PM ----------

This doesn't mention strings but it has a lot of great info about coding efficiently.

http://community.bistudio.com/wiki/Code_Optimisation

Share this post


Link to post
Share on other sites

I was just messing around with a random group spawn script. This is what i have so far, i haven't even tested it yet, I'm sure there would be some problems with the random statement though, as I've just changed what was a normal array to the current nested array you see.Plus I don't even know if "in" is a proper command to see if object or w/e is in an array. I didn't even check haha

if (!isServer) exitWith {};

_group = _this select 0;
_spawnLocation = _this select 1;
_destination = _this select 2;

_groupArray = [

              ["RU_InfSquad","RU_InfSection","RU_InfSection_AT","RU_InfSection_AA","RU_InfSection_MG","RU_SniperTeam","RUS_ReconTeam","MVD_AssaultTeam"],
              ["RU_MotInfSquad","RU_MotInfSection_Recon","RU_MotInfSection_Patrol"],
              ["RU_MechInfSquad_1","RU_MechInfSquad_2"],
              ["RU_TankPlatoon"]

             ];


_randomGroup = _groupArray select (floor(random(count _groupArray)));

if (_randomGroup in _groupArray select 1) then {_group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> _randomGroup)] call BIS_fnc_spawnGroup};
if (_randomGroup in _groupArray select 2) then {_group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Motorized" >> _randomGroup)] call BIS_fnc_spawnGroup};
if (_randomGroup in _groupArray select 3) then {_group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Mechanized" >> _randomGroup)] call BIS_fnc_spawnGroup};
if (_randomGroup in _groupArray select 4) then {_group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Armored" >> _randomGroup)] call BIS_fnc_spawnGroup};

Share this post


Link to post
Share on other sites

Your using configs to spawn the groups so there is no reason to define them like that in the _groupArray. Just use a substitute. ie:

something like this:

if (!isServer) exitWith {};

_group = _this select 0;
_spawnLocation = _this select 1;
_destination = _this select 2;




//1 = Inf
//2 = Mot
//3 = Mech
//4 = Tank
_groupArray = [1,2,3,4];


// There is a function for this:
// http://community.bistudio.com/wiki/BIS_fnc_selectRandom
//_randomGroup = _groupArray select (floor(random( _groupArray)));


_randomGroup = _groupArray call BIS_fnc_selectRandom;






switch (_randomGroup) do
{
   case 1:
   {
   _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> _randomGroup)] call BIS_fnc_spawnGroup;
   };


   case 2:
   {
   _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Motorized" >> _randomGroup)] call BIS_fnc_spawnGroup;
   };


   /// Etc
};

Share this post


Link to post
Share on other sites

Thanks. I was using a switch do, in my initial script. It got pretty large haha. I basically just wanted to add all of the groups into one pool, random from the pool once, and then spawn the group with only a few lines of code.

my old script

private ["_group", "_spawnLocation","_randomGroup","_groupArray"];

_group = _this select 0;
_spawnLocation = _this select 1;

_groupArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
_randomGroup = _groupArray select (floor(random(count _groupArray)));

switch (_randomGroup) do

    {
        case 1:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_InfSquad")] call BIS_fnc_spawnGroup;
        };

        case 2:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_InfSection")] call BIS_fnc_spawnGroup;
        };

        case 3:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_InfSection_AT")] call BIS_fnc_spawnGroup;
        };

        case 4:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_InfSection_MG")] call BIS_fnc_spawnGroup;
        };

        case 5:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_InfSection_MG")] call BIS_fnc_spawnGroup;
        };

        case 6:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RU_SniperTeam")] call BIS_fnc_spawnGroup;
        };

        case 7:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "RUS_ReconTeam")] call BIS_fnc_spawnGroup;
        };

        case 8:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry" >> "MVD_AssaultTeam")] call BIS_fnc_spawnGroup;
        };

        case 9:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Motorized" >> "RU_MotInfSquad")] call BIS_fnc_spawnGroup;
        };

        case 10:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Motorized" >> "RU_MotInfSection_Recon")] call BIS_fnc_spawnGroup;
        };

        case 11:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Motorized" >> "RU_MotInfSection_Patrol")] call BIS_fnc_spawnGroup;
        };

        case 12:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Mechanized" >> "RU_MechInfSquad_1")] call BIS_fnc_spawnGroup;
        };

        case 13:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Mechanized" >> "RRU_MechInfSquad_2")] call BIS_fnc_spawnGroup;
        };

        case 14:

        {
            _group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> "Armored" >> "RU_TankPlatoon")] call BIS_fnc_spawnGroup;
        };



   };


nul=[_group, position _spawnLocation, 150] call BIS_fnc_taskPatrol;

Share this post


Link to post
Share on other sites

Nothing wrong with that script, much more efficient that the OP one you posted.

Don't worry about how many lines of code you have till you start getting over 250 per .sqf. As long as its coded well it will run great.

Share this post


Link to post
Share on other sites

Why do you say it's not efficient? Is it because of the if statements? Could you elaborate why the if statements or comparing is bad? i didn't know this.

Share this post


Link to post
Share on other sites

Its the comparing of the strings that makes it much less efficient.

The if statements are not to bad. It is a little less efficient, but its ok to do it sometimes. With a switch statement the engine will stop analizing the statement after it finds the correct case. If you just use all if's then it will compare each one every time.

Share this post


Link to post
Share on other sites

That's good to know. Since I'm learning here, how would I go through the entire nested array and randomly select an element from anyone of the given (nested) arrays? ie; randomly select one of those cfgGroups. If I just use random normally, it just selects from one of the nested arrays and not the elements (group types) in those arrays.

_groupArray = [

              ["RU_InfSquad","RU_InfSection","RU_InfSection_AT","RU_InfSection_AA","RU_InfSection_MG","RU_SniperTeam","RUS_ReconTeam","MVD_AssaultTeam"],
              ["RU_MotInfSquad","RU_MotInfSection_Recon","RU_MotInfSection_Patrol"],
              ["RU_MechInfSquad_1","RU_MechInfSquad_2"],
              ["RU_TankPlatoon"]

             ];


_randomGroup = _groupArray select (floor(random(count _groupArray)))

Edited by Iceman77

Share this post


Link to post
Share on other sites

hi guys, apologies for jumping into this thread but I have been working on something similar and am struggling with one aspect: -

My random group spawning script is this, and works as expected:

for [{_i=0}, {_i<(random 20)}, {_i=_i+1}] do
{
_egroup = ["I44_A_PltnHQ","I44_A_Assault","I44_A_BAR","I44_A_Rifle","I44_A_Recon","I44_A_Bazooka","I44_A_MG","I44_A_Engr"];
_regroup = [];
_regroup = _egroup select floor(random(count _egroup));
_sgroup = [getmarkerPos "m1", WEST, (configFile >> "CfgGroups" >> "i44_a" >> "i44_a_army" >> "I44_A_Army_Men" >> _Regroup)] call BIS_fnc_spawnGroup;
};

What I then want to do is pass something like this over each of the spawned groups:

nul = {[_x, getmarkerPos "m1", 400, true] execvm "Bin_taskPatrol.sqf"} foreach _sgroup;

however basically it seems _sgroup is not an array of the groups that have been spawned, which leaves me a little stumped. Any ideas?

In fact, thinking about this, _sgroup is probably just going to be the last group created isn't it? So I guess I need a way to pass each group into an array as it is created.

...which is what I did and it works. New script:

_allthegroups =[];
for [{_i=0}, {_i<(random 20)}, {_i=_i+1}] do
{
_egroup = ["I44_A_PltnHQ","I44_A_Assault","I44_A_BAR","I44_A_Rifle","I44_A_Recon","I44_A_Bazooka","I44_A_MG","I44_A_Engr"];
_regroup = [];
_regroup = _egroup select floor(random(count _egroup));
_sgroup = [getmarkerPos "m1", WEST, (configFile >> "CfgGroups" >> "i44_a" >> "i44_a_army" >> "I44_A_Army_Men" >> _Regroup)] call BIS_fnc_spawnGroup;
_allthegroups = _allthegroups + [_sgroup];
};

nul = {[_x, getmarkerPos "m1", 400, true] execvm "Bin_taskPatrol.sqf"} foreach _allthegroups;

Edited by jiltedjock

Share this post


Link to post
Share on other sites

yeah I've read that and other things about nested arrays. None of them show how to access the actual elements inside the nested arrays randomly. Anyhow, I'm sure someone that knows will respond :o

Share this post


Link to post
Share on other sites

How about something like this:

_groupArray = [
              ["RU_InfSquad","RU_InfSection","RU_InfSection_AT","RU_InfSection_AA","RU_InfSection_MG","RU_SniperTeam","RUS_ReconTeam","MVD_AssaultTeam"],
              ["RU_MotInfSquad","RU_MotInfSection_Recon","RU_MotInfSection_Patrol"],
              ["RU_MechInfSquad_1","RU_MechInfSquad_2"],
              ["RU_TankPlatoon"]
             ];

_typeI = (floor(random(count _groupArray)));
_randomGroup = _groupArray select _type;
_randomGroupType = _randomGroup select (floor(random(count _randomGroup)));

_type = switch (_typeI) do {
 case 0: { "Infantry"; };
 case 1: { "Motorized"; };
 case 2: { "Mechanized"; };
 case 3: { "Armored"; };
}

_group = [[color=#333333]getPos _spawnLocation[/color], EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> _type >> _randomGroupType)] call BIS_fnc_spawnGroup;

Or do the _type as an array:

_types = ["Infantry", "Motorized", "Mechanized", "Armored"];
_type = _types select _typeI;

Or use another dimension:

_groupArray = [
              ["Infantry", ["RU_InfSquad","RU_InfSection","RU_InfSection_AT","RU_InfSection_AA","RU_InfSection_MG","RU_SniperTeam","RUS_ReconTeam","MVD_AssaultTeam"]],
              ["Motorized", ["RU_MotInfSquad","RU_MotInfSection_Recon","RU_MotInfSection_Patrol"]],
              ["Mechanized", ["RU_MechInfSquad_1","RU_MechInfSquad_2"]],
              ["Armored", ["RU_TankPlatoon"]]
             ];

Edited by Sickboy

Share this post


Link to post
Share on other sites

Or you could read directly from the config:

_config = (configFile >> "CfgGroups" >> "East" >> "RU" >> "Infantry");
_group = [getPos _spawnLocation, EAST, _config select (floor(random count _config))] call BIS_fnc_spawnGroup;

This however lacks some control, although you can build on it of course.

Share this post


Link to post
Share on other sites

How would i use another dimension like that? Could you further elaborate sickboy?

Share this post


Link to post
Share on other sites

Sure, here's the example complete, with the extra dimension:

_groupArray = [
              ["Infantry", ["RU_InfSquad","RU_InfSection","RU_InfSection_AT","RU_InfSection_AA","RU_InfSection_MG","RU_SniperTeam","RUS_ReconTeam","MVD_AssaultTeam"]],
              ["Motorized", ["RU_MotInfSquad","RU_MotInfSection_Recon","RU_MotInfSection_Patrol"]],
              ["Mechanized", ["RU_MechInfSquad_1","RU_MechInfSquad_2"]],
              ["Armored", ["RU_TankPlatoon"]]
             ];

_randomGroup = _groupArray select (floor(random(count _groupArray))); // Randomly select type category
_type = _randomGroup select 0; // Select type category name
_randomGroups = _randomGroup select 1; // Select available group types in the category
_randomGroupType = _randomGroups select (floor(random(count _randomGroups))); // Finally randomly select one of the group types.

_group = [getPos _spawnLocation, EAST, (configFile >> "CfgGroups" >> "East" >> "RU" >> _type >> _randomGroupType)] call BIS_fnc_spawnGroup;

However, it is far more complex than the example of selecting directly on the config - although that example lacks more fine grained control.

Edited by Sickboy

Share this post


Link to post
Share on other sites

This is good info, and if you want to build on that, check out Rube's library. Part of the heart of his work is "tagging" function parameters.

This removes all the "_this select 0, _this select 1" etc. Trying to remember in some script calls which have 5 or more parameters can get to be a headache...

Here's a bit from Rube:

1) Function Parameters - tag them. Goddamn it!

     Unless there is only a small and fixed number of parameters, go on as usual. 
     But if there are more of them, and even more could be added later, and 
     especially if there are optional parameters(!), use friggin tagged parameters 
     (an array of [key, value]).

     For one, parameters are tagged/labeled, which makes reading code so much 
     easier. Second, the order of the parameters doesn't matter at all, which makes
     adding more (hopefully optional to not break backwards comp.) parameters later
     very easy.

     Need an example?
     [color="#FF0000"]Guess which one is better[/color]:

       a) ["Peter", 34, 1.2, 7, true, true false] call _function

       b) [
             ["name", "Peter"],
             ["age", 34],
             ["score", 1.2],
             ["deaths", 7],
             ["noob", true],
             ["ugly", true],
             ["nice", false]
          ] call _function

     Got it? Fine. And if not, well, screw you!

That's exactly from the readme, not me :D

And an example of how to read the parameters in your function, from Rube library fn_spawnFactionGroup:

_type = "";
_faction = "GUE";
_group = grpNull;
_newGroup = false;
_position = [0,0,0];
_direction = random 360;
_composite = [];
_vehicles = [];
_vehiclePosOffset = 8;
_special = "";
_moveInCargo = false;

_customSelection = [];

// read parameters
{
  switch (_x select 0) do
  {
     case "type": { 
        if ((typeName (_x select 1)) == "ARRAY") then
        {
           _type = "custom";
           _customSelection = (_x select 1); 
        } else
        {
           _type = _x select 1;
        };
     };
     case "faction": { _faction = _x select 1; };
     case "group": { _group = _x select 1; };
     case "position": { _position = _x select 1; };
     case "direction": { _direction = _x select 1; };
     case "special": { _special = _x select 1; };
     case "moveInCargo": { _moveInCargo = _x select 1; };
  };
} forEach _this;
//

Edited by panther42

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
Sign in to follow this  

×