Jump to content
Sign in to follow this  
lxets

Changing array

Recommended Posts

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

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 by sarogahtyp

Share this post


Link to post
Share on other sites

Tested these out and found the 2nd one is fastest, thanks for the solutions.

Share this post


Link to post
Share on other sites

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


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
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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×