SRL Archive - OSR Help

Searching for list of strings in a 2D string array


ZeroInstance

2011-08-30 21:31:42

Okay, so I have this Array of TStringArray, where the values are as follows:
FirstArray := [['A', '1'], ['B', '2'], ['C', '3'], ['D', '4'], ['E', '5']]
And I also have an array with the following values:
SecondArray := ['B', 'E', 'C']
What I'm attempting to do is to see if all of the strings from the second array are in the first group of indexes of the first array, but in no particular order, and if it is, then perform a task. I can't seem to find a way to program it.

In the examples above, the result would be true since all three of the strings in the second array are in the first values of the tstringarray. It would also be beneficial to be able to determine which index each value is; in this case, it would be 1, 4, 2.

Any ideas? I know I didn't do a good job at explaining, but I hope it makes sense


EDIT:
Another way to explain would be like this; I want to do something like the following:
if(ArrayContains(FirstArray, SecondArray) then
What would I put in the function ArrayContains?

i luffs yeww

2011-08-30 22:39:01

Will the values always be like that? (Increasing by one, starting at 1?)

ZeroInstance

2011-08-30 22:45:59

From: i luffs yeww
Will the values always be like that? (Increasing by one, starting at 1?)

No, it'll be random, words even.

Thanks

weequ

2011-08-30 23:17:30

I didn't understand yet why you need to use 2D array in the FirstArray.


Edit:
This?:
"It would also be beneficial to be able to determine which index each value is; in this case, it would be 1, 4, 2."

ZeroInstance

2011-08-30 23:26:50

From: weequ
I didn't understand yet why you need to use 2D array in the FirstArray.


FirstArray[0][0] := 'A';
FirstArray[0][1] := '1';
FirstArray[1][0] := 'B';
FirstArray[1][1] := '2';
FirstArray[2][0] := 'C';
FirstArray[2][1] := '3';

SecondArray := ['C', 'B'];
1, 2, and 3 will be used somewhere else; I'm just saying that this is how I have it.

From: weequ
Edit:
This?:
"It would also be beneficial to be able to determine which index each value is; in this case, it would be 1, 4, 2."



In this case, the result would be true, since C and B are both found in FirstArray[0] where i doesn't have a specific order. I'd like to know the value of i for each item in SecondArray.

Thanks

EDIT:
There might even be two of the same values in SecondArray

EDIT 2:
To better understand what I'm trying to achieve, I'll give you an unrelated example that would fit this situation. Suppose you are playing cards and are dealt three cards. You want to see if two of those cards are two specific cards. This is how it would fit into this situation:

FirstArray[0] := ['Two', 'Diamonds'];
FirstArray[1] := ['Four', 'Hearts'];
FirstArray[2] := ['Nine', 'Spades'];

SecondArray := ['Nine', 'Four'];
The result would give us a True, as you have both a four and a nine, and the indexes are 1 and 2, as it's those cards that are the ones listed in the SecondArray.

I don't know of a better way to explain what I'm looking for.

Thanks.

weequ

2011-08-30 23:57:00

I wrote this code that you can try and see if it works as supposed to.
Also when you read through the code maybe you can understand how it was done ;)
Also let me know if you need more help.

program new;
var
FirstArray: Array of TStringArray;
SecondArray: TStringArray;


function StringArrayContains(S: String; SA: TStringArray): Integer;
var
I: Integer;
begin
for I := 0 to High(SA) do
begin
if (SA[I] = S) then
begin
Result := I;
Exit;
end;
end;
Result := -1; //No matches, setting value to -1.
end;

function ABC(SA: TStringArray; SSA: Array of TStringArray): Integer;
var
I, II, III: Integer;
begin
for I := 0 to High(SA) do
for II := 0 to High(SSA) do
for III := 0 to High(SSA[II]) do
begin
if (SA[I] = SSA[II][III]) then
begin
Result := II;
Exit;
end;
end;
Result := -1; //No matches, setting value to -1.
end;



begin
SetLength(FirstArray, 5);
FirstArray[0] := ['A', '1'];
FirstArray[1] := ['B', '2'];
FirstArray[2] := ['C', '3'];
FirstArray[3] := ['D', '4'];
FirstArray[4] := ['E', '5'];;
SecondArray := ['B', 'E', 'C'];
WriteLn(IntToStr(ABC(SecondArray, FirstArray)));
end.
Currently it stops looking after first match. Could easily modify it to search through it all and return an array containing the first indexes. It could also be modified to return the second indexes too and the position in the SecondArray.

ZeroInstance

2011-08-31 00:32:33

From: weequ
I wrote this code that you can try and see if it works as supposed to.
Also when you read through the code maybe you can understand how it was done ;)
Also let me know if you need more help.

Currently it stops looking after first match. Could easily modify it to search through it all and return an array containing the first indexes. It could also be modified to return the second indexes too and the position in the SecondArray.


Can you point me in a direction for how to have it search for each string?
Thanks

The StringArrayContains function works flawlessly when searching a regular TStringArray. Why isn't it a default function included in Simba?

Other than that, this is impressive! I spent two hours getting close but to no avail.

Thanks

i luffs yeww

2011-08-31 00:38:12

I don't know what either of you have been talking about (too lazy to read), but what weequ posted seems far more complicated than it needs to.

I've been busy with rs (lulwut), but I could write something up right quick if necessary.

All you need to do is nest your loops and compare. Add values as necessary for the result.

ZeroInstance

2011-08-31 00:43:22

From: i luffs yeww
I don't know what either of you have been talking about (too lazy to read), but what weequ posted seems far more complicated than it needs to.

I've been busy with rs (lulwut), but I could write something up right quick if necessary.

All you need to do is nest your loops and compare. Add values as necessary for the result.


If you read my EDIT 2 in my post before his, I explain in short what I'm looking for, with an example. What he posted does partly what I was looking for though. What do you mean by nest your loops and compare?

Thanks

weequ

2011-08-31 00:47:36

Anyway this is basically same as above but with all the matches.

I'd love to see your version of this i luffs yeww.

program new;
var
FirstArray: Array of TStringArray;
SecondArray: TStringArray;
J: Integer;
IA: TIntegerArray;

function ABC(SA: TStringArray; SSA: Array of TStringArray): TIntegerArray;
var
I, II, III: Integer;
begin
for I := 0 to High(SA) do
for II := 0 to High(SSA) do
for III := 0 to High(SSA[II]) do
begin
if (SA[I] = SSA[II][III]) then
begin
SetLength(Result, Length(Result)+1);
Result[High(Result)] := II;
end;
end;
end;



begin
SetLength(FirstArray, 5);
FirstArray[0] := ['A', '1'];
FirstArray[1] := ['B', '2'];
FirstArray[2] := ['C', '3'];
FirstArray[3] := ['D', '4'];
FirstArray[4] := ['E', '5'];;
SecondArray := ['B', 'E', 'C'];
IA := ABC(SecondArray, FirstArray);
for J := 0 to High(IA) do
begin
WriteLn('Match #'+IntToStr(J+1)+' is '+IntToStr(IA[J]));
end;
end.

ZeroInstance

2011-08-31 01:00:23

From: weequ
Anyway this is basically same as above but with all the matches.

I'd love to see your version of this i luffs yeww.


Wow, barely any differences… Just out of curiosity, how do those lines work? Does it add the Integer to a new index in the Result Array?

SetLength(Result, Length(Result)+1);
Result[High(Result)] := II;


Thanks a lot, by the way!
+REP

weequ

2011-08-31 01:12:56

Yes those lines work just like you said.

First it makes space for the Integer by increasing the Length of the array by one and then it gives the last Integer in the Array the value of II.

ZeroInstance

2011-08-31 19:53:51

Alright, thanks a lot! That saved me a lot of time

Dgby714

2011-08-31 21:22:40

Bored scripting….

program new;

function FindEt(const name: string; out Arr: TVariantArray; const Data: array of TVariantArray): boolean;
var
H, I, J, K: Integer;
begin
Result := False;
H := High(Data);
for I := 0 to H do
if (Length(Data[I]) > 0) then
if (String(Data[I][0]) = Name) then
begin
SetLength(Arr, Length(Data[I]));
J := High(Data[I]);
for K := 0 to J do
Arr[K] := Data[I][K];
Break;
end;

if (Length(Arr) > 0) then
begin
Result := True;
H := High(Arr);
for I := 1 to H do
Arr[I - 1] := Arr[I];
SetLength(Arr, Length(Arr) - 1);
end;
end;

var
Data: array of TVariantArray;
Et: TVariantArray;

begin
SetLength(Data, 3);
Data[0] := ['test', 42, True];
Data[1] := ['hmmm', False];
Data[2] := ['-'];

WriteLn(FindEt('test', Et, Data)); //True
WriteLn(Et); // [42, True]

WriteLn(FindEt('hmmm', Et, Data)); //True
WriteLn(Et); // [False]

WriteLn(FindEt('-', Et, Data)); //True
WriteLn(Et); // []

WriteLn(FindEt('Nothing', Et, Data)); //False
WriteLn(Et); // []
end.

ZeroInstance

2011-08-31 21:44:44

From: Dgby714
Bored scripting….



What does that do?

Dgby714

2011-08-31 21:49:27

From: ZeroInstance
What does that do?


The main loop gives you an example of how to use it. (begin..end)

ZeroInstance

2011-08-31 23:58:16

From: Dgby714
The main loop gives you an example of how to use it. (begin..end)


Oh I see, thanks