lxets 3 Posted June 24, 2016 Hi, basically im trying to convert an array, the best I can explain this is probably through an example, so _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = [[1,4],[2,1],[3,3],[4,2],[5,1]]; I have got this working, but there are some issues which is why im trying to understand the best way to do this. Here is the code I have { _number = _x; _count = {_x == _number} count _oldArray; _oldArray = _oldArray - [_number]; _newArray pushBack [_x,_count]; } forEach _oldArray; Using the code above I will get: [[1,4],[1,0],[1,0],[1,0],[2,1],[3,3],[3,0],[3,0],[4,2],[4,0],[5,1]] which is not ideal. I can get around this by doing the following. From: _newArray pushBack [_x,_count]; To: if (_count > 0) then { _newArray pushBack [_x,_count]; }; That will give me [[1,4],[2,1],[3,3],[4,2],[5,1]] which is the result I wanted, but I don't think the method is ideal. Im probably really over complicating this, but Im not sure what the ideal way to do it is. Share this post Link to post Share on other sites
sarogahtyp 1105 Posted June 24, 2016 (edited) I come up with this: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; { _element = _x; _count ={(_element == _x)} count _oldArray; _newArray pushBackUnique [_x,_count]; true }count _oldArray; systemChat str _newArray; but it could be that this is faster: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; { _newArray pushBackUnique _x; true }count _oldArray; _newArray = _newArray apply { _element = _x; _count ={(_element == _x)} count _oldArray; [_x, _count] }; systemChat str _newArray; it shortens the array before counting elements. i think its faster with large arrays. and here is a hybrid solution of both: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; _tempArray = []; { if(!(_x in _temp_array)) then { _tempArray pushBack _x; _element = _x; _count = {(_element == _x)} count _oldArray; _newArray pushBack [_x,_count]; }; true }count _oldArray; systemChat str _newArray; but I think its slower than 2nd solution because of the (_x in array) check if ur array is sorted (or all equal elements r always neighbours) as shown in ur example then u could use this one: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; _last_element = ""; { if(_x != _last_element) then { _element = _x; _count ={(_element == _x)} count _oldArray; _newArray pushBack [_x, _count]; } _last_element =_x; true }count _oldArray; systemChat str _newArray; but u should test urself which solution is fastest. I would bet on 2nd or 4th solution... another solution with the condition that equal elements r neighbours is this: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; _last_element = ""; _newArray = (_oldArray select { _not_equal = false; if (_x != _last_element) then {_not_equal = true;}; _last_element = _x; _not_equal }) apply { _element = _x; _count ={(_element == _x)} count _oldArray; [_x, _count] }; systemChat str _newArray; its chaining select and apply command which someone told me would be powerfull. but its on u to do some speed tests with the speedometer at bottom left of the debug console... Edited June 24, 2016 by sarogahtyp Share this post Link to post Share on other sites
lxets 3 Posted June 24, 2016 Tested these out and found the 2nd one is fastest, thanks for the solutions. Share this post Link to post Share on other sites
sarogahtyp 1105 Posted June 24, 2016 3rd and 4th solution were not workin. just tested it now and here they r: _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; _last_element = ""; { if(!(_x isEqualTo _last_element)) then { _element = _x; _count ={(_element == _x)} count _oldArray; _newArray pushBack [_x, _count]; }; _last_element =_x; true }count _oldArray; systemChat str _newArray; _oldArray = [1,1,1,1,2,3,3,3,4,4,5]; _newArray = []; _last_element = ""; _newArray = (_oldArray select { _not_equal = false; if (!(_x isEqualTo _last_element)) then {_not_equal = true;}; _last_element = _x; _not_equal }) apply { _element = _x; _count ={(_element == _x)} count _oldArray; [_x, _count] }; systemChat str _newArray; Share this post Link to post Share on other sites
serena 150 Posted June 24, 2016 Fn_CombineElements = { private _res = []; { private _elm = _x; private _rec = {if (_x select 0 isEqualTo _elm) exitWith {_x}} forEach _res; if (isNil {_rec}) then {_res pushBack [_elm, 1]} else {_rec set [1, 1 + (_rec select 1)]} } forEach _this; _res }; [3,1,1,1,2,3,1,3,4,5,4] call Fn_CombineElements; // Result: [[3,3],[1,4],[2,1],[4,2],[5,1]] Share this post Link to post Share on other sites
Grumpy Old Man 3540 Posted June 24, 2016 BIS_fnc_consolidateArray Cheers 2 Share this post Link to post Share on other sites
killzone_kid 1326 Posted June 25, 2016 Fn_CombineElements = { private _res = []; { private _elm = _x; private _rec = {if (_x select 0 isEqualTo _elm) exitWith {_x}} forEach _res; if (isNil {_rec}) then {_res pushBack [_elm, 1]} else {_rec set [1, 1 + (_rec select 1)]} } forEach _this; _res }; [3,1,1,1,2,3,1,3,4,5,4] call Fn_CombineElements; // Result: [[3,3],[1,4],[2,1],[4,2],[5,1]] isNil {_rec} is slower than isNil "_rec". {} version should be used when you have expression to evaluate. Share this post Link to post Share on other sites