Posts: 795
Threads: 136
Joined: Feb 2009
Hi Gintaras, Hi all,
I must test a string variable to a huge bunch of other strings. (>50)
StrSel is what i used, but it's not convenient when there is many many strings to test.
A loop using foreach is what i used , but seems too long.
IStringmap is also a possibility from examples in QM I use now.
My best bet would be something like StrSel, but the tested strings would be in an array filled from a text file.
How to achieve something like:
str test2.getfile("$desktop$\test.txt")
_s="somethingtotest"
int result=SelStr(17 _s test2)
if(result!=0)
action...
Does it exit?
What can you give as advice to best handle that?
thanks
Posts: 12,090
Threads: 142
Joined: Dec 2002
IStringMap is exactly for this purpose.
Macro Macro1950
str test2.getfile("$desktop$\test.txt")
IStringMap m=CreateStringMap(1|2)
m.AddList(test2)
_s="somethingtotest"
if m.Get(_s)
,out "found"
Posts: 135
Threads: 33
Joined: Aug 2009
QM help says:
"If you want to add simple list of strings (keys without values), you can use "[]" as sep to avoid breaking strings into keys and values."
If I add the above text in test.txt and use sep="[]"
Macro Macro289
str test2.getfile("$desktop$\test.txt")
IStringMap m=CreateStringMap(1|2)
m.AddList(test2 "[]")
_s="you"
if m.Get(_s)
,out "found"
else out "not found"
_s="you" => not found
Please, how to find any word in a huge text?
Posts: 12,090
Threads: 142
Joined: Dec 2002
The file must be multiline
If
you
want
...
Do you need string index in the list?
What separator is used in your list?
Posts: 135
Threads: 33
Joined: Aug 2009
I misunderstood the use of IstringMap.
Anyway, thanks for your prompt reply. Much appreciated.
Posts: 795
Threads: 136
Joined: Feb 2009
Ok, i was then right to use IStringMap and will stick to it.
Anyway, i'd like to use sel to behave on matching string.
How to get index of found string in IStringMap? did not find
in QM help...
Posts: 12,090
Threads: 142
Joined: Dec 2002
IStringMap sorts strings, because searching in a sorted list is much faster. Indices are lost.
What is list format?
string1
string2
...
or
string1, value1
string2, value2
...
or
string1 string2...
or...
Posts: 795
Threads: 136
Joined: Feb 2009
the first one, only a list of words...
one
two
three
four
etc etc
Posts: 12,090
Threads: 142
Joined: Dec 2002
foreach is fast.
Function SelStrInList
;/
function# $sList $sFind [flags] ;;flags: 1 case insens
;Returns 1-based index of string in a list, or 0 if not found.
;sList - multiline list of single-line strings.
;sFind - string to find.
int i(1) ins(flags&1)
str s
foreach s sList
,if(!StrCompare(s sFind ins)) ret i
,i+1
Posts: 795
Threads: 136
Joined: Feb 2009
actually, i tried that way, but ditched it for IStringMap because I
thought
it would be faster/lightweight.
Eventually, the list to be matched will contain up to 800/1000 strings.
Which method is most suitable for searching in then?
Posts: 12,090
Threads: 142
Joined: Dec 2002
foreach average time with 1000 strings is 100 microseconds with 1.6 G CPU.
IStringMap is faster (if created once, searched many times, and if number of strings is big enough), but cannot be used if need string index.
Posts: 795
Threads: 136
Joined: Feb 2009
Ok, my i7 laptop with 8 Go RAM will do fine then.
I'll use foreach if index is needed,
iStringMap if only matching is needed without index.
Seems fair to you?
Posts: 795
Threads: 136
Joined: Feb 2009
I was thinking about creating a global array at QM launch, so it would be available for all searches .
For index in IStringMap, i was thinking about
using a list like (in test.txt)
"wordone" "1"
"wordtwo" "2"
wordthree" "3"
and so on.
Not much work.
Would this code work, and/or does it make sense?
str test2.getfile("$desktop$\test.txt")
IStringMap m=CreateStringMap(1|2)
m.AddList(test2)
_s="somethingtotest"
int index=m.Get(_s)
out index
Sel index
case 1: action1
case 2: action2
case else end
Right code?
Posts: 12,090
Threads: 142
Joined: Dec 2002
Macro Macro1996
out
;create list of random strings for testing
str sList sFind
rep 1000
,sFind.RandomString(10 10 "a-z")
,sList.addline(sFind)
;out sList
;create map. Add indices now. Time 1100 us.
IStringMap m=CreateStringMap(1|2)
int i=1; str s
foreach(s sList) m.IntAdd(s i); i+1
;find string and get its index. Time 2 us.
if(!m.IntGet(sFind i)) i=0
out i
Posts: 795
Threads: 136
Joined: Feb 2009
Yeap, must better, as usual. Thanks Gintaras
Posts: 795
Threads: 136
Joined: Feb 2009
OK, cleaned some codes from advices given in last questions.
Now arise a new question:
I have _s containing some paths
_s=
c:\program files\myexe51.exe
c:\program files\myexe2.exe
c:\program files\myexe3.exe
c:\program files\myexe4.exe
c:\program files\myexe5.exe
and i have an array or another string variable of words
ARRAY(str) a1 or str s1="myexe1 mystuff anotherone somethingelse"
All tricks (IStringmaps, SelStr, StrCompare) will work on words alone, not with a find function.
I'd like to make another string/array with words in s1 or a1 matched in _s, and one with unmatched.
I tried many ways, found one with an intermediate array which works, but sure there must be simpler way.
What I did
foreach str'r _s
foreach str'rr s1
if(find(rr r)>-1) doaction
but i can't get the place to put unmatched words.
Thanks for help.
Posts: 12,090
Threads: 142
Joined: Dec 2002
Macro Macro1990
out
str s=
;c:\program files\myexe1.exe
;c:\program files\myexe2.exe
;c:\program files\myexe3.exe
;c:\program files\myexe4.exe
;c:\program files\anotherone.exe
str sw=
;myexe1
;mystuff
;anotherone
;somethingelse
ARRAY(str) am au
foreach _s sw
,if(findw(s _s)<0) au[]=_s
,else am[]=_s
out "<><Z 0x80c080>Matched</Z>"
out am
out "<><Z 0x80c080>Unmatched</Z>"
out au
Posts: 795
Threads: 136
Joined: Feb 2009
Damned, I knew it would be simple, but I did not try findw on purpose
as Help file says "find whole word" and I searched for substring. Fooled again.
The ouput color trick is wonderful, will use it extensively....
Thanks Gintaras
Posts: 795
Threads: 136
Joined: Feb 2009
Would it be possible to sort s too in your example, in matched/unmatched form?
Posts: 12,090
Threads: 142
Joined: Dec 2002
Macro Macro1989
out
str s=
;c:\program files\myexe1.exe
;c:\program files\myexe2.exe
;c:\program files\myexe3.exe
;c:\program files\myexe4.exe
;c:\program files\anotherone.exe
str sw=
;myexe1
;mystuff
;anotherone
;somethingelse
ARRAY(str) am au AM AU
foreach _s sw
,if(findw(s _s)<0) au[]=_s
,else am[]=_s
foreach _s s
,for(_i 0 am.len) if(findw(_s am[_i])>=0) break
,if(_i<am.len) AM[]=_s; else AU[]=_s
out "<><Z 0x80c080>Matched</Z>"
out am
out "<><Z 0x80c080>Unmatched</Z>"
out au
out "<><Z 0xc0c0>Matched</Z>"
out AM
out "<><Z 0xc0c0>Unmatched</Z>"
out AU
Posts: 795
Threads: 136
Joined: Feb 2009
Well, your code works of course, but not for me.
In fact, the generic strings I gave as examples are not formatted the way I use them, so I think the
problem come from there.
I'll try to make it on my own, and will post tomorrow a new thread if I can't, with real code.
I now sleep on that...
Posts: 795
Threads: 136
Joined: Feb 2009
OK, back from work.
Indeed, i managed to adapt the code to work for me.
I misused tok function, as I used something like
"c:\thepathto\myoprogram"*"somearguments" form as parsing string, but it screwed up until i use
the 4 flag in tok function and remove the * and used space instead.
Thread close.
|