Jump to content
jwllorens

Return most prolific element in array?

Recommended Posts

I have an array of strings, eg:  ["tskATK_LumberYard_WEST","tskATK_DieselPlant_WEST","tskATK_LumberYard_WEST","tskATK_LumberYard_WEST","tskATK_TempleRuins_WEST","tskATK_DieselPlant_WEST"]

 

I need to return the string that appears most often in this array.  Is there a command to do this?  Or a fast way to do this?

 

In the above example, I would need it to return "tskATK_LumberYard_WEST" because this string appears three times in the array, which is more than any other string appears in the array..

Share this post


Link to post
Share on other sites

I have an array of strings, eg:  ["tskATK_LumberYard_WEST","tskATK_DieselPlant_WEST","tskATK_LumberYard_WEST","tskATK_LumberYard_WEST","tskATK_TempleRuins_WEST","tskATK_DieselPlant_WEST"]

 

I need to return the string that appears most often in this array.  Is there a command to do this?  Or a fast way to do this?

 

In the above example, I would need it to return "tskATK_LumberYard_WEST" because this string appears three times in the array, which is more than any other string appears in the array..

I've done this in a hideous way but here is a start for you:

_arr = [
	"tskATK_LumberYard_WEST",
	"tskATK_DieselPlant_WEST",
	"tskATK_LumberYard_WEST",
	"tskATK_LumberYard_WEST",
	"tskATK_TempleRuins_WEST",
	"tskATK_DieselPlant_WEST"
];

_arr = _arr apply {
	private _str = _x;
	[
		{_x isEqualTo _str} count _arr,
		_x
	];
};

_arr = _arr arrayIntersect _arr;
_arr sort false;

(_arr select 0 select 1);
// Returns "tskATK_LumberYard_WEST"

EDIT:

Actually, I don't think you even need the arrayIntersect line.

Edited by hallyg

Share this post


Link to post
Share on other sites

There are BI functions that will do this for you if you dont feel like writing your own.

_arr =  ["tskATK_LumberYard_WEST","tskATK_DieselPlant_WEST","tskATK_LumberYard_WEST","tskATK_LumberYard_WEST","tskATK_TempleRuins_WEST","tskATK_DieselPlant_WEST"];
_arr = _arr call BIS_fnc_consolidateArray;
_arr = [ _arr, [], _x select 1, "DESCEND" ] call BIS_fnc_sortBy;
_most = _arr select 0 select 0;
  • Like 1

Share this post


Link to post
Share on other sites

This is what I came up with but I can't test it yet. If anyone has a better idea im all ears.
 

params ["_array"];
_elems = [];
{
  _elems pushBackUnique _x;
  true
} count _array;
_elems = _elems apply {
  _y = _x;
  [({_y isEqualTo _x} count _array),_y]
};
sort _elems false;
(_elems select 0) select 1

Share this post


Link to post
Share on other sites

I realized that rarely would you need the most prolific element in an array without needing all the elements that were considered but rejected.  Rather than repeat the task of isolating all unique elements in the array, I took a look at my function and poked around to see if I could re-use the results of some of the operations that were performed for finding the most prolific element in order to also return the unique elements that were not the most prolific.

 

Why?  For example, if you need the most prolific element to do some task (choose one of many markers and change the color to indicate that the region is "active", in my case) then you would also need all the elements that were rejected in order to iterate through them and ensure that they do not need to have their color changed back if they were previously active.

 

So I adapted the function to return an array in the following form:

 

[_mostCommonElement,_arrayOfAllOtherElements]

 

where _arrayOfAllOtherElements contains only unique values from the original array passed to the function that were also not the most prolific element.

params ["_array"];_elmts = [];
{
  _elmts pushBackUnique _x;
  true
} count _array;
_elmts2 = _elmts apply {
  _y = _x;
  [({_y isEqualTo _x} count _array),_y]
};
sort _elmts2 false;
_mCom = (_elmts2 select 0) select 1;
_lCom = (_elmts - _mCom);
[_mCom,_lCom]

I don't know.  It "looks" fast, it is just a few lines of code.  

 

But it does use two loops, one of which is n^2 (ouch).  Could have scary overhead if you pass it a huge array.  For my purposes I will be passing it an array that is equal to the number of players on the server.  So it will run one loop equal to the number of array elements passed to it, and another n^2 loop equal to the number of unique elements in the array times the number of elements in the array that was passed to the function.

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

×