{"name":"Array","title":"Array","type":"topic","url":"https://community.bistudio.com/wiki/Array","revid":378805,"updated":"2026-06-29T16:53:01Z","aliases":[],"markdown":"An **Array** is a list of items of varying variable types (including other arrays). Different types can coexist within the same array.\n\nSee also: Arrays\n\n> [!WARNING]\n> Since Arma 3 v1.56, arrays are limited to maximum of **9,999,999** (sometimes 10,000,000) elements.\n\n### Working With Arrays\n\n#### Array Properties\n\nAn array variable is a **reference** to the array (see [Wikipedia reference page](https://en.wikipedia.org/wiki/Reference_(computer_science)));\nthis means that if the array is edited, all the scripts/functions using a reference to this array will see the edition.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = _myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // will be \"z\"\n```\n\nAn array set through setVariable does not need to be assigned again if you modify it by reference:\n\n```sqf\nplayer setVariable [\"myArray\", [\"a\", \"b\", \"c\"]];\nprivate _myArray = player getVariable \"myArray\";\n_myArray set [1, \"z\"];\nplayer getVariable \"myArray\"; // is [\"a\", \"z\", \"c\"]\n```\n\n#### Array Creation\n\n```sqf\n// Example of an empty array\nprivate _myArray = [];\ncount _myArray;            // returns 0\n\n// Example of a filled array\nprivate _myFilledArray = [\"abc\", \"def\"];\ncount _myFilledArray;    // returns 2\n```\n\nAn array can hold another array within it, that can hold another array itself, etc:\n\n```sqf\nprivate _myArray = [[\"my\", \"subArray\", 1], [\"mySubArray2\"], [[\"my\", \"sub\", \"sub\", \"array\"]]];\ncount   _myArray;                        // returns 3\ncount  (_myArray select 0);                // returns 3\ncount  (_myArray select 1);                // returns 1\ncount  (_myArray select 2);                // returns 1\ncount ((_myArray select 2) select 0);    // returns 4\n```\n\n#### Getting an element\n\nAn array uses a zero-based index for its elements:\n\n```sqf\nprivate _myArray = [\"first item\", \"second item\", \"third item\"];\n_myArray select 0;    // returns \"first item\"\n_myArray # 2;        // returns \"third item\" - Arma 3 only\n```\n\n#### Setting an Element\n\n```sqf\nprivate _myArray = [\"first item\", \"second item\", \"third item\"];\n_myArray select 1;                    // returns \"second item\"\n_myArray set [1, \"hello there\"];    // _myArray is [\"first item\", \"hello there\", \"third item\"]\n```\n\n> [!IMPORTANT]\n> If the index given to the set command is out of bounds, the array will resize to incorporate the index *as its last value*.\n> All the \"empty spaces\" between the last valid element and the new set element will be filled with nil\n\n#### Counting elements\n\n```sqf\nprivate _myArray = [\"first item\", [\"second item's subitem 1\", \"second item's subitem 2\"], \"third item\"];\ncount _myArray; // returns 3 - arrays are not counted recursively\n```\n\n#### Changing array size\n\nThe resize command is made to reduce or expand an array:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray resize 3; // _myArray is [\"a\", \"b\", \"c\"]\n```\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray resize 5; // _myArray is [\"a\", \"b\", \"c\", nil, nil]\n```\n\n> [!IMPORTANT]\n> You do **not** need to extend an array before adding any elements.\n\n#### Array Copy\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = _myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // will be \"z\"\n```\n\n```sqf\nprivate _myArray = [[\"a\", \"b\", \"c\"], [\"d\", \"e\", \"f\"]];\nprivate _subArray1 = _myArray select 0;\n_subArray1 set [1, \"z\"];\n// _subArray1 is now [\"a\", \"z\", \"c\"]\n// _myArray is now [[\"a\", \"z\", \"c\"], [\"d\", \"e\", \"f\"]]\n```\n\nIn order to avoid this behaviour, **copy** the array with + (plus):\n\n```sqf\n// making copy\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = +_myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // still \"b\"\n```\n\nSub-arrays are also deep-copied; `_myNewArray` will not point at the same sub-array instances.\n\n#### Adding (Appending) Elements\n\nIn Arma 3 use append and pushBack commands:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray pushBack \"d\";        // _myArray is [\"a\", \"b\", \"c\", \"d\"] - pushback = add the element at the end\n_myArray append [\"e\", \"f\"];    // _myArray is [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"] - append = pushback for each provided items\n```\n\nYou could also use the plus (+) operator to add arrays.\nThe difference is that addition returns a copy of array and thus a little slower than append and pushBack, which modify the target array.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray = _myArray + [\"d\"];        // _myArray is [\"a\", \"b\", \"c\", \"d\"]\n_myArray = _myArray + [\"e\", \"f\"];    // _myArray is [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n#### Removing (Deleting) Elements\n\nIn Arma 3 the deleteAt and deleteRange commands are available:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray deleteAt 0; // _myArray is [\"b\", \"c\", \"d\", \"e\"]\n```\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray deleteRange [1, 2];    // _myArray is [\"a\", \"d\", \"e\"]\n```\n\nYou can also use the minus (-) operator to subtract arrays.\nThe subtraction returns array copy, just like addition, and is not as fast as deleteAt and deleteRange which modify target arrays.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray = _myArray - [\"a\"]; // _myArray is [\"b\", \"c\", \"d\", \"e\"]\n```\n\nIn Arma 3 it became possible to also subtract nested arrays:\n\n```sqf\nprivate _myArray = [[\"a\", \"b\", \"c\"], [\"d\", \"e\", \"f\"], [\"g\", \"h\", \"i\"]];\n_myArray = _myArray - [[\"d\", \"e\", \"f\"]]; // _myArray is [[\"a\", \"b\", \"c\"], [\"g\", \"h\", \"i\"]]\n```\n\nThe subtraction will remove *all* elements of the second array from the first one:\n\n```sqf\n_myArray = [\"a\", \"b\", \"c\", \"a\", \"b\", \"c\"] - [\"a\", \"b\"]; // _myArray is [\"c\", \"c\"]\n```\n\nThe solution to this issue is the combined use of set and an item that you know is **not** present in the array:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"a\", \"b\", \"c\"];\n_myArray set [2, objNull];            // _myArray is [\"a\", \"b\", objNull, \"a\", \"b\", \"c\"]\n_myArray = _myArray - [objNull];    // _myArray is [\"a\", \"b\", \"a\", \"b\", \"c\"]\n```\n\nUsing this technique, it is possible to mimic deleteRange behaviour this way:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n{ _myArray set [_x, objNull] } forEach [1, 2];    // _myArray is [\"a\", objNull, objNull, \"d\", \"e\"]\n_array = _array - [objNull];                    // _myArray is [\"a\", \"d\", \"e\"]\n```\n\n#### Going Through the Array\n\nThe simplest way to iterate through an array is the forEach command:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n{ systemChat _x } forEach _myArray;\n```\n\nA combination of for, count and select can also be used:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\nfor \"_i\" from 0 to (count _myArray) -1 do { // count returns 5, but it is a zero-based index\n    systemChat (_myArray select _i);\n};\n```\n\n### Advanced Usage\n\n#### apply\n\nSimilar to the [\"map\" function in Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),\napply allows to apply code to every elements in an array and return a copy:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n_myArray = _myArray apply { _x * 2 }; // _myArray is [2, 4, 6, 8, 10]\n\n// same as (but faster than)\n_myArray = + _myArray;\nfor \"_i\" from 0 to count _myArray -1 do\n{\n    private _element = _myArray select _i;\n    _myArray set [_i, _element * 2];\n};\n```\n\n#### select\n\nA simple way to filter an array (and obtain a new one) is using select's alternative syntax:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\nprivate _filteredArray = _myArray select { _x > 3 }; // _filteredArray is [4, 5]\n\n// same as\nprivate _filteredArray = [];\n{ if (_x > 3) then { _filteredArray pushBack _x } } forEach _myArray;\n```\n\n#### findIf\n\nThe findIf command was introduced in Arma 3 and allows you to go through the whole list and stop **as soon as the condition is met**, returning the condition-meeting element's array index:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n_myArray findIf { _x == 3 } > -1; // returns true, meaning there is an element that equals 3\n_myArray findIf { _x == 6 } > -1; // returns false, meaning there is no element that is equal to 6\n```\n\nYou could use count to achieve the same result, however count won't stop until it iterated through the whole array, so it might take longer.\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n{ _x == 3 } count _myArray > 0; // returns true, meaning there is an element that equals 3\n{ _x == 6 } count _myArray > 0; // returns false, meaning there is no element that is equal to 6\n```\n\n#### arrayIntersect\n\nThe arrayIntersect command returns a new array filled with the items found in both provided lists:\n\n```sqf\nprivate _array1 = [1, 2, 3, 4];\nprivate _array2 = [3, 4, 5, 6];\nprivate _result = _array1 arrayIntersect _array2; // _result is [3, 4]\n```\n\n**You can remove duplicates (get unique items) with this command:**\n\n```sqf\nprivate _myArray = [1, 2, 2, 3, 4];\nprivate _result = _myArray arrayIntersect _myArray; // _result is [1, 2, 3, 4]\n```\n\nBe wary that nil elements get removed by this method:\n\n```sqf\nprivate _myArray = [1, 2, nil, 3, 4];\nprivate _result = _myArray arrayIntersect _myArray; // _result is [1, 2, 3, 4]\n```\n\n#### Selective Removal\n\nSelectively filter out single elements from `_arrayA` based on `_arrayB`.\n\nThis is useful in the case where *some* duplicates must be removed.\n\n```sqf\nprivate _arrayA = [1, 2, 3, 2, 4, 5, 4];\nprivate _arrayB = [2, 2, 4];\n\n{\n    private _index = _arrayA find _x;\n    if (_index != -1) then\n    {\n        _arrayA deleteAt _index;\n    };\n} forEach _arrayB;\n\n_arrayA; // is now [1, 3, 5, 4]\n```\n\n#### Sorting\n\n##### sort\n\nThe sort command allows for sorting an array of String, Number or sub-Arrays of string/number. It modifies the original array and **does not return anything**:\n\n```sqf\nprivate _myArray = [\"zzz\", \"aaa\", \"ccc\"];\n_myArray sort true; // _myArray is [\"aaa\", \"ccc\", \"zzz\"]\n```\n\n```sqf\nprivate _myArray = [666, 57, 1024, 42];\n_myArray sort false; // _myArray is [1024, 666, 57, 42]\n```\n\n```sqf\nprivate _myArray = [[\"zzz\", 0], [\"aaa\", 42], [\"ccc\", 33]];\n_myArray sort true; // _myArray is [[\"aaa\", 42], [\"ccc\", 33], [\"zzz\", 0]]\n```\n\n##### reverse\n\nThe reverse command simply reverses the array order:\n\n```sqf\nprivate _myArray = [99, 33, 17, 24, \"a\", [3,2,1], 7777];\nreverse _myArray; // _myArray is [7777, [3,2,1], \"a\", 24, 17, 33, 99]\n```\n\n##### BIS_fnc_sortBy\n\nThe function BIS_fnc_sortBy has been created for more complex sorting. Its algorithm input must return a number:\n\n```sqf\nprivate _closestHelicopters = [[_heli1, _heli2, _heli3], [], { player distance _x }, \"ASCEND\"] call BIS_fnc_sortBy;\n```\n\n### Common Errors\n\n#### Index Rounding\n\nIn Real Virtuality scripts, indices are rounded to the nearest whole number.\nA boundary case (X.5, where X is any whole number) rounds to the nearest **even** whole number.\n\n**Boundary cases:**\n- -0.5 <= index <= 0.5 rounds to 0\n-  0.5 <  index <  1.5 rounds to 1\n-  1.5 <= index <= 2.5 rounds to 2\n-  2.5 <  index <  3.5 rounds to 3\n\n**In short:**\n- -0.5 rounds **up** to 0\n-  0.5 rounds **down** to 0\n-  1.5 rounds **up** to 2\n-  2.5 rounds **down** to 2\n-  3.5 rounds **up** to 4\netc.\n\n> [!NOTE]\n> This behaviour is different from random's behaviour.\n\n#### Index out of Range\n\nThe following code lists Arma 3 behaviour on wrong indices:\n\n```sqf\nprivate _myArray = [\"element0\"];\n_myArray select -1; // throws a Error Zero Divisor error message\n_myArray select  0; // returns \"element0\"\n_myArray select  1; // returns nil\n_myArray select  2; // throws a Error Zero Divisor error message\n```\n\n##### param\n\nUse the param command in order to avoid out of range error:\n\n```sqf\nprivate _myArray = [0, 1, 2];\n_myArray select 5;            // error: out of range\n_myArray param [5];            // returns nil\n_myArray param [5, \"abc\"];    // returns default value \"abc\" on invalid index\n```\n\n> [!NOTE]\n> See also params to define multiple items at once.\n\n##### set\n\nIf the index given to the set command is out of bounds:\n- if the index rounded to a negative number, then an Error Zero Divisor message will be displayed in game.\n- if the index rounded to a positive number, then the array will resize to incorporate the index *as its last value*. Each element between the last valid element, and the new set element, will be the null type\n\n#### Zero Divisor\n\nSee above - a used array index may be negative.\n\n#### Unexpected \",\"\n\nThis error originates from a bad syntax:\n\n```sqf\nprivate _myErroneousArray = [\"Weapon1\", \"Weapon2\", \"Weapon3\",]; // The last element in an array must not end by \",\"\n\n// this mostly happens in vertical arrays\nprivate _myErroneousArray = [\n    \"element1\",\n    \"element2\",\n    \"element3\", // this one comma is wrong\n];\n```\n\n#### Reserved variable in expression\n\nThis issue arises when trying to modify a read-only array (such as select arrays that are returned from an addon, or eventually a trigger's thisList).\n\nTo combat this, *copy* said array with the plus (+) command before modifying:\n\n```sqf\nprivate _readOnlyArray = thisList;    // assuming the code is called from within a trigger\n_readOnlyArray set [1, \"test\"];        // Error: Reserved variable in expression - thisList return value is read-only\n\n// No Error\nprivate _normalArray = +_readOnlyArray;    // shallow-copy the array instead of using a reference\n_normalArray set [1, \"test\"];            // perfectly fine\n```\n\n### See Also\n\n- Arrays\n- Command Group: Arrays\n- Function Group: Arrays","sections":[{"heading":null,"level":1,"markdown":"An **Array** is a list of items of varying variable types (including other arrays). Different types can coexist within the same array.\n\nSee also: Arrays\n\n> [!WARNING]\n> Since Arma 3 v1.56, arrays are limited to maximum of **9,999,999** (sometimes 10,000,000) elements."},{"heading":"Working With Arrays","level":3,"markdown":""},{"heading":"Array Properties","level":4,"markdown":"An array variable is a **reference** to the array (see [Wikipedia reference page](https://en.wikipedia.org/wiki/Reference_(computer_science)));\nthis means that if the array is edited, all the scripts/functions using a reference to this array will see the edition.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = _myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // will be \"z\"\n```\n\nAn array set through setVariable does not need to be assigned again if you modify it by reference:\n\n```sqf\nplayer setVariable [\"myArray\", [\"a\", \"b\", \"c\"]];\nprivate _myArray = player getVariable \"myArray\";\n_myArray set [1, \"z\"];\nplayer getVariable \"myArray\"; // is [\"a\", \"z\", \"c\"]\n```"},{"heading":"Array Creation","level":4,"markdown":"```sqf\n// Example of an empty array\nprivate _myArray = [];\ncount _myArray;            // returns 0\n\n// Example of a filled array\nprivate _myFilledArray = [\"abc\", \"def\"];\ncount _myFilledArray;    // returns 2\n```\n\nAn array can hold another array within it, that can hold another array itself, etc:\n\n```sqf\nprivate _myArray = [[\"my\", \"subArray\", 1], [\"mySubArray2\"], [[\"my\", \"sub\", \"sub\", \"array\"]]];\ncount   _myArray;                        // returns 3\ncount  (_myArray select 0);                // returns 3\ncount  (_myArray select 1);                // returns 1\ncount  (_myArray select 2);                // returns 1\ncount ((_myArray select 2) select 0);    // returns 4\n```"},{"heading":"Getting an element","level":4,"markdown":"An array uses a zero-based index for its elements:\n\n```sqf\nprivate _myArray = [\"first item\", \"second item\", \"third item\"];\n_myArray select 0;    // returns \"first item\"\n_myArray # 2;        // returns \"third item\" - Arma 3 only\n```"},{"heading":"Setting an Element","level":4,"markdown":"```sqf\nprivate _myArray = [\"first item\", \"second item\", \"third item\"];\n_myArray select 1;                    // returns \"second item\"\n_myArray set [1, \"hello there\"];    // _myArray is [\"first item\", \"hello there\", \"third item\"]\n```\n\n> [!IMPORTANT]\n> If the index given to the set command is out of bounds, the array will resize to incorporate the index *as its last value*.\n> All the \"empty spaces\" between the last valid element and the new set element will be filled with nil"},{"heading":"Counting elements","level":4,"markdown":"```sqf\nprivate _myArray = [\"first item\", [\"second item's subitem 1\", \"second item's subitem 2\"], \"third item\"];\ncount _myArray; // returns 3 - arrays are not counted recursively\n```"},{"heading":"Changing array size","level":4,"markdown":"The resize command is made to reduce or expand an array:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray resize 3; // _myArray is [\"a\", \"b\", \"c\"]\n```\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray resize 5; // _myArray is [\"a\", \"b\", \"c\", nil, nil]\n```\n\n> [!IMPORTANT]\n> You do **not** need to extend an array before adding any elements."},{"heading":"Array Copy","level":4,"markdown":"```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = _myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // will be \"z\"\n```\n\n```sqf\nprivate _myArray = [[\"a\", \"b\", \"c\"], [\"d\", \"e\", \"f\"]];\nprivate _subArray1 = _myArray select 0;\n_subArray1 set [1, \"z\"];\n// _subArray1 is now [\"a\", \"z\", \"c\"]\n// _myArray is now [[\"a\", \"z\", \"c\"], [\"d\", \"e\", \"f\"]]\n```\n\nIn order to avoid this behaviour, **copy** the array with + (plus):\n\n```sqf\n// making copy\nprivate _myArray = [\"a\", \"b\", \"c\"];\nprivate _myNewArray = +_myArray;\n_myArray set [1, \"z\"];\n_myNewArray select 1; // still \"b\"\n```\n\nSub-arrays are also deep-copied; `_myNewArray` will not point at the same sub-array instances."},{"heading":"Adding (Appending) Elements","level":4,"markdown":"In Arma 3 use append and pushBack commands:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray pushBack \"d\";        // _myArray is [\"a\", \"b\", \"c\", \"d\"] - pushback = add the element at the end\n_myArray append [\"e\", \"f\"];    // _myArray is [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"] - append = pushback for each provided items\n```\n\nYou could also use the plus (+) operator to add arrays.\nThe difference is that addition returns a copy of array and thus a little slower than append and pushBack, which modify the target array.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\"];\n_myArray = _myArray + [\"d\"];        // _myArray is [\"a\", \"b\", \"c\", \"d\"]\n_myArray = _myArray + [\"e\", \"f\"];    // _myArray is [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```"},{"heading":"Removing (Deleting) Elements","level":4,"markdown":"In Arma 3 the deleteAt and deleteRange commands are available:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray deleteAt 0; // _myArray is [\"b\", \"c\", \"d\", \"e\"]\n```\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray deleteRange [1, 2];    // _myArray is [\"a\", \"d\", \"e\"]\n```\n\nYou can also use the minus (-) operator to subtract arrays.\nThe subtraction returns array copy, just like addition, and is not as fast as deleteAt and deleteRange which modify target arrays.\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n_myArray = _myArray - [\"a\"]; // _myArray is [\"b\", \"c\", \"d\", \"e\"]\n```\n\nIn Arma 3 it became possible to also subtract nested arrays:\n\n```sqf\nprivate _myArray = [[\"a\", \"b\", \"c\"], [\"d\", \"e\", \"f\"], [\"g\", \"h\", \"i\"]];\n_myArray = _myArray - [[\"d\", \"e\", \"f\"]]; // _myArray is [[\"a\", \"b\", \"c\"], [\"g\", \"h\", \"i\"]]\n```\n\nThe subtraction will remove *all* elements of the second array from the first one:\n\n```sqf\n_myArray = [\"a\", \"b\", \"c\", \"a\", \"b\", \"c\"] - [\"a\", \"b\"]; // _myArray is [\"c\", \"c\"]\n```\n\nThe solution to this issue is the combined use of set and an item that you know is **not** present in the array:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"a\", \"b\", \"c\"];\n_myArray set [2, objNull];            // _myArray is [\"a\", \"b\", objNull, \"a\", \"b\", \"c\"]\n_myArray = _myArray - [objNull];    // _myArray is [\"a\", \"b\", \"a\", \"b\", \"c\"]\n```\n\nUsing this technique, it is possible to mimic deleteRange behaviour this way:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n{ _myArray set [_x, objNull] } forEach [1, 2];    // _myArray is [\"a\", objNull, objNull, \"d\", \"e\"]\n_array = _array - [objNull];                    // _myArray is [\"a\", \"d\", \"e\"]\n```"},{"heading":"Going Through the Array","level":4,"markdown":"The simplest way to iterate through an array is the forEach command:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\n{ systemChat _x } forEach _myArray;\n```\n\nA combination of for, count and select can also be used:\n\n```sqf\nprivate _myArray = [\"a\", \"b\", \"c\", \"d\", \"e\"];\nfor \"_i\" from 0 to (count _myArray) -1 do { // count returns 5, but it is a zero-based index\n    systemChat (_myArray select _i);\n};\n```"},{"heading":"Advanced Usage","level":3,"markdown":""},{"heading":"apply","level":4,"markdown":"Similar to the [\"map\" function in Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),\napply allows to apply code to every elements in an array and return a copy:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n_myArray = _myArray apply { _x * 2 }; // _myArray is [2, 4, 6, 8, 10]\n\n// same as (but faster than)\n_myArray = + _myArray;\nfor \"_i\" from 0 to count _myArray -1 do\n{\n    private _element = _myArray select _i;\n    _myArray set [_i, _element * 2];\n};\n```"},{"heading":"select","level":4,"markdown":"A simple way to filter an array (and obtain a new one) is using select's alternative syntax:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\nprivate _filteredArray = _myArray select { _x > 3 }; // _filteredArray is [4, 5]\n\n// same as\nprivate _filteredArray = [];\n{ if (_x > 3) then { _filteredArray pushBack _x } } forEach _myArray;\n```"},{"heading":"findIf","level":4,"markdown":"The findIf command was introduced in Arma 3 and allows you to go through the whole list and stop **as soon as the condition is met**, returning the condition-meeting element's array index:\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n_myArray findIf { _x == 3 } > -1; // returns true, meaning there is an element that equals 3\n_myArray findIf { _x == 6 } > -1; // returns false, meaning there is no element that is equal to 6\n```\n\nYou could use count to achieve the same result, however count won't stop until it iterated through the whole array, so it might take longer.\n\n```sqf\nprivate _myArray = [1, 2, 3, 4, 5];\n{ _x == 3 } count _myArray > 0; // returns true, meaning there is an element that equals 3\n{ _x == 6 } count _myArray > 0; // returns false, meaning there is no element that is equal to 6\n```"},{"heading":"arrayIntersect","level":4,"markdown":"The arrayIntersect command returns a new array filled with the items found in both provided lists:\n\n```sqf\nprivate _array1 = [1, 2, 3, 4];\nprivate _array2 = [3, 4, 5, 6];\nprivate _result = _array1 arrayIntersect _array2; // _result is [3, 4]\n```\n\n**You can remove duplicates (get unique items) with this command:**\n\n```sqf\nprivate _myArray = [1, 2, 2, 3, 4];\nprivate _result = _myArray arrayIntersect _myArray; // _result is [1, 2, 3, 4]\n```\n\nBe wary that nil elements get removed by this method:\n\n```sqf\nprivate _myArray = [1, 2, nil, 3, 4];\nprivate _result = _myArray arrayIntersect _myArray; // _result is [1, 2, 3, 4]\n```"},{"heading":"Selective Removal","level":4,"markdown":"Selectively filter out single elements from `_arrayA` based on `_arrayB`.\n\nThis is useful in the case where *some* duplicates must be removed.\n\n```sqf\nprivate _arrayA = [1, 2, 3, 2, 4, 5, 4];\nprivate _arrayB = [2, 2, 4];\n\n{\n    private _index = _arrayA find _x;\n    if (_index != -1) then\n    {\n        _arrayA deleteAt _index;\n    };\n} forEach _arrayB;\n\n_arrayA; // is now [1, 3, 5, 4]\n```"},{"heading":"Sorting","level":4,"markdown":""},{"heading":"sort","level":5,"markdown":"The sort command allows for sorting an array of String, Number or sub-Arrays of string/number. It modifies the original array and **does not return anything**:\n\n```sqf\nprivate _myArray = [\"zzz\", \"aaa\", \"ccc\"];\n_myArray sort true; // _myArray is [\"aaa\", \"ccc\", \"zzz\"]\n```\n\n```sqf\nprivate _myArray = [666, 57, 1024, 42];\n_myArray sort false; // _myArray is [1024, 666, 57, 42]\n```\n\n```sqf\nprivate _myArray = [[\"zzz\", 0], [\"aaa\", 42], [\"ccc\", 33]];\n_myArray sort true; // _myArray is [[\"aaa\", 42], [\"ccc\", 33], [\"zzz\", 0]]\n```"},{"heading":"reverse","level":5,"markdown":"The reverse command simply reverses the array order:\n\n```sqf\nprivate _myArray = [99, 33, 17, 24, \"a\", [3,2,1], 7777];\nreverse _myArray; // _myArray is [7777, [3,2,1], \"a\", 24, 17, 33, 99]\n```"},{"heading":"BIS_fnc_sortBy","level":5,"markdown":"The function BIS_fnc_sortBy has been created for more complex sorting. Its algorithm input must return a number:\n\n```sqf\nprivate _closestHelicopters = [[_heli1, _heli2, _heli3], [], { player distance _x }, \"ASCEND\"] call BIS_fnc_sortBy;\n```"},{"heading":"Common Errors","level":3,"markdown":""},{"heading":"Index Rounding","level":4,"markdown":"In Real Virtuality scripts, indices are rounded to the nearest whole number.\nA boundary case (X.5, where X is any whole number) rounds to the nearest **even** whole number.\n\n**Boundary cases:**\n- -0.5 <= index <= 0.5 rounds to 0\n-  0.5 <  index <  1.5 rounds to 1\n-  1.5 <= index <= 2.5 rounds to 2\n-  2.5 <  index <  3.5 rounds to 3\n\n**In short:**\n- -0.5 rounds **up** to 0\n-  0.5 rounds **down** to 0\n-  1.5 rounds **up** to 2\n-  2.5 rounds **down** to 2\n-  3.5 rounds **up** to 4\netc.\n\n> [!NOTE]\n> This behaviour is different from random's behaviour."},{"heading":"Index out of Range","level":4,"markdown":"The following code lists Arma 3 behaviour on wrong indices:\n\n```sqf\nprivate _myArray = [\"element0\"];\n_myArray select -1; // throws a Error Zero Divisor error message\n_myArray select  0; // returns \"element0\"\n_myArray select  1; // returns nil\n_myArray select  2; // throws a Error Zero Divisor error message\n```"},{"heading":"param","level":5,"markdown":"Use the param command in order to avoid out of range error:\n\n```sqf\nprivate _myArray = [0, 1, 2];\n_myArray select 5;            // error: out of range\n_myArray param [5];            // returns nil\n_myArray param [5, \"abc\"];    // returns default value \"abc\" on invalid index\n```\n\n> [!NOTE]\n> See also params to define multiple items at once."},{"heading":"set","level":5,"markdown":"If the index given to the set command is out of bounds:\n- if the index rounded to a negative number, then an Error Zero Divisor message will be displayed in game.\n- if the index rounded to a positive number, then the array will resize to incorporate the index *as its last value*. Each element between the last valid element, and the new set element, will be the null type"},{"heading":"Zero Divisor","level":4,"markdown":"See above - a used array index may be negative."},{"heading":"Unexpected \",\"","level":4,"markdown":"This error originates from a bad syntax:\n\n```sqf\nprivate _myErroneousArray = [\"Weapon1\", \"Weapon2\", \"Weapon3\",]; // The last element in an array must not end by \",\"\n\n// this mostly happens in vertical arrays\nprivate _myErroneousArray = [\n    \"element1\",\n    \"element2\",\n    \"element3\", // this one comma is wrong\n];\n```"},{"heading":"Reserved variable in expression","level":4,"markdown":"This issue arises when trying to modify a read-only array (such as select arrays that are returned from an addon, or eventually a trigger's thisList).\n\nTo combat this, *copy* said array with the plus (+) command before modifying:\n\n```sqf\nprivate _readOnlyArray = thisList;    // assuming the code is called from within a trigger\n_readOnlyArray set [1, \"test\"];        // Error: Reserved variable in expression - thisList return value is read-only\n\n// No Error\nprivate _normalArray = +_readOnlyArray;    // shallow-copy the array instead of using a reference\n_normalArray set [1, \"test\"];            // perfectly fine\n```"},{"heading":"See Also","level":3,"markdown":"- Arrays\n- Command Group: Arrays\n- Function Group: Arrays"}],"categories":["Data Types"],"groups":["Data Types"]}