Jump to content
Sign in to follow this  
Heeeere's johnny!

How to "find" subarray by element of that subarray?

Recommended Posts

Hi,

I have a small issue here. I've got an array looking like this

[[3, "someString"], [14, "anotherString"], [7, "yetAString"]] //and so on

Just for the sake of performance, is it somehow possible to get a whole subarray [number, string] using the "find" command on this array of arrays if I search by the string or do I have to loop through it (count/forEach)?

Regards,

waltenberg aka Johnny

Edited by waltenberg

Share this post


Link to post
Share on other sites

Not sure what you mean exactly, but this should work:

found = [[3, "someString"], [14, "anotherString"], [7, "yetAString"]] find [14, "anotherString"]

If you want to do a partial match, you either have to use forEach, or use an index-array.

Share this post


Link to post
Share on other sites

Well, let me make it a bit clearer.

Let's call the array "_superArray":

_superArray = [[3, "someString"], [14, "anotherString"], [7, "yetAString"]]; //and so on

_superArray is being extended and shrunk at runtime and the numbers are being randomized in that process, only the strings are known to the player as they are hardcoded, but that's not relevant.

So that means, I cannot search by the whole subarray as I don't know the number, I only know the string. That's why I was asking if it was possible to search a whole subarray using "find" or if I had to manually loop through the array using "count" or "forEach".

I hope that clears it up.

Regards,

waltenberg

Edited by waltenberg

Share this post


Link to post
Share on other sites

I don't completely understand your question. Probably way off base here :p

_num = (_superArray select 0) find "someString" // finds "someString" in the first array within _superarray?

Edited by Iceman77

Share this post


Link to post
Share on other sites

I don't think there's a predefined BIS function that can search nested arrays. I know you're smart enough to write your own function though, waltenberg.

Screw it, I freaking love nested loops and nested arrays.

/*
USAGE: _result = [P1, P2] call DREAD_fnc_findInNestedArray;

RETURNS: An array containing the element of the array the desired result was found on, and
the element of the result within that array. If the element is not found, result will be
an array with a single element consisting of "Not Found".

	P1: ARRAY - Array you want to test.
	P2: ANY - Element you want to find.

EXAMPLE: _superArray = [[12, "apple"], [5, "orange"], [17, "banana"]];
	   _result = [_superArray, "banana"] call DREAD_fnc_findInNestedArray;
RETURNS: [3, 2]

NOTE: Function will stop and return position at first found element.
NOTE: Arrays of all sizes can be input, as long as they are only nested one deep.
*/

DREAD_fnc_findInNestedArray =
{
private ["_result", "_result2", "_stopLoop", "_found"];
{
	_stopLoop = false;
	{
		_found = false;
		_result2 = _forEachIndex;
		if (str _x == str(_this select 1)) then
		{
			_stopLoop = true;
			_found = true;
		};
		if (str _x == str(_this select 1)) exitWith {_result2};
	}forEach _x;
	_result = [_forEachIndex + 1, _result2 + 1];
	if (_stopLoop) exitWith {_result};
}forEach (_this select 0);

if (!_found) then
{
	_result = ["Not Found"];
};
_result;
};

Tested and confirmed working for Numbers and Strings. Not sure about other variable types though.

---------- Post added at 03:08 ---------- Previous post was at 02:58 ----------

Iceman gave me an idea, you could probably do something with this:

DREAD2 =
{
{
	_x find (_this select 1);
}forEach (_this select 0);
};

Usage is currently set up to be the same, but you'll have to add your own result-returning and breakouts. Also, untested.

Edited by DreadedEntity

Share this post


Link to post
Share on other sites
I don't completely understand your question. Probably way off base here :p

_num = (_superArray select 0) find "someString" // finds "someString" in the first array within _superarray?

Sorry, but yes, you are off base here. :p

I know you're smart enough to write your own function though, waltenberg.

Thanks, appreciated. ^_^

Screw it, I freaking love nested loops and nested arrays.

Yeah, I do so, too. But at the same time, I very often think about maximizing their efficiency when they are heavily used.

Your findInNestedArray's functionality to find subarrays of dynamic length is useful so thank you. But it's a bit "too powerful" for my needs. ;)

As I was lying in my bed last evening, I had a different idea. Instead of making n nested arrays, I thought of two subarrays of length n where the first one would contain the string and the second one the number, like this:

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

That way, I could use "find" on the string array and with the returned index, I could get the number of the number array:

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
_number = (_superArray select 1) select _i;

Still needs testing though as I don't know if "find" is faster than a "forEach" or "count" (with a custom index parameter) which could do the job on n subarrays as you put it down. Might be an interesting point on Code Optimisation. ;)

Edited by waltenberg

Share this post


Link to post
Share on other sites

_num = (_superArray select 0) find "someString" // finds "someString" in the first array within _superarray?

Sorry, but yes, you are off base here.

...

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
_number = (_superArray select 0) select _number;

Still needs testing though as I don't know if "find" is faster than a "forEach" or "count" (with a custom index parameter) which could do the job on n subarrays as you put it down. Might be an interesting point on Code Optimisation. ;)

Looks like I was pretty spot on.

Share this post


Link to post
Share on other sites

Well, now as I've decided to change this whole thing from

[[5, "sub1"], [12, "sub2"] ...];

to

[["sub1", "sub2", ...], [5, 12, ...]];

yeah, admittedly you are. ^_^

Share this post


Link to post
Share on other sites

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
_number = (_superArray select 0) select _number;

something looks wrong here, maybe try:

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
if (_i != -1) then //returned value will be -1 if searched element was not found
{
_number = (_superArray select 1) select _i;
}else
{
hint "Element was not found.";
};

Share this post


Link to post
Share on other sites
_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
_number = (_superArray select 0) select _number;

something looks wrong here, maybe try:

_superArray = [["apples", "oranges", "bananas", "kiwis"], [3, 17, 9, 5]];

_i = (_superArray select 0) find "oranges";
if (_i != -1) then //returned value will be -1 if searched element was not found
{
   _number = (_superArray select 1) select _i;
}else
{
   hint "Element was not found.";
};

Oops, my bad - corrected.

Yeah, I know the issue about -1, but I omitted this, because of lazyness. ;) But thanks for pointing it out.

Share this post


Link to post
Share on other sites
Yeah, I know the issue about -1, but I omitted this, because of lazyness. ;) But thanks for pointing it out.

Ah okay, I'm sure you already know about this, but if you tried to "select -1" it would throw a "Generic Error in Expression" error because -1 is not a valid index. Also, in case it wasn't clear what I changed, I changed _number to _i in the second line. It would likely throw "Undefined variable in expression: _number" as there was no code to pre-define it.

Share this post


Link to post
Share on other sites

*derp* I must have been sleeping... Thanks. :rolleyes:

---------- Post added at 17:15 ---------- Previous post was at 17:10 ----------

If I execute "_superArray find nil", I get "scalar" if I hint the result. What does that mean? What if I wanted to find the first nil in that array? Can I not use "find" for that?

Share this post


Link to post
Share on other sites
If I execute "_superArray find nil", I get "scalar" if I hint the result. What does that mean? What if I wanted to find the first nil in that array? Can I not use "find" for that?

Google: What is a scalar?

I guess you could consider that it's the engine's way of saying "Something is here but that's all I can tell."

Share this post


Link to post
Share on other sites

Hmm, well ... I'd rather consider it the engine's way to say "Syntactially correct, but I don't know what to do." as "find nil" is probably as saying "In that array, give me the index of nothing/anything.".

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  

×