I would suggest code like follows to determine the position of an item in a list:
set searchitem to "B"
set mylist to {"A", "B", "C"}
set listlength to length of mylist
repeat with i from 1 to listlength
set listitem to item i of mylist
considering case
if listitem is equal to searchitem then
display dialog searchitem & " is at position " & i & " in the list!"
end if
end considering
end repeat
Martin’s search doesn’t exit the repeat loop when the candidate is found, so it checks the entire list. Here are two alternatives – the first a linear search that exits when it finds the index, and the second a binary search that’s much more efficient if the list is long. Neither will deal with repeats of the sought for item – they only find one:
set L to {"alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"}
set C to count L
-- a binary search for a term in an unsorted list requires checking whether the search term is contained in a subset of the list in a binary fashion: is it in the first half, if yes, is it in the first quarter, if yes is it in the first eighth, etc. Most binary search algorithms presume a sorted list; this "20 questions" technique does not. Since the Greek alphabet has 24 characters, dividing that down to 1 by halves requires 5 comparisons (the next larger binary number is 32 = 2^5.
-- Linear search; requires, on average, traversing half the list.
set F to some item of L -- this chooses one at random but you would use the term you were searching for.
repeat with k from 1 to C
if item k of L is F then
set idx to k
exit repeat
end if
end repeat
-- Binary search; (for C > 2^(N - 1) and C ≤ 2^N) always requires N tests
set V to F -- again just using a random pick rather than a specific item.
set I to binarySearch(L, V)
on binarySearch(theList, theValue)
script o
property lst : theList
end script
set theValueAsList to {theValue}
set L to 1
set r to (count o's lst)
if (theValueAsList is in theList) then
repeat until (theValue is item L of o's lst)
set L to L + 1
set m to (L + r) div 2
if (theValueAsList is in items L thru m of o's lst) then
set r to m - 1
else
set L to m + 1
end if
end repeat
return L
else
return 0
end if
end binarySearch
The binary search was too complicated for me so I settled for a combination of both your suggestions
on get_loc(searchitem, mylist)
repeat with i from 1 to 26 -- 26 characters in the alphabet
if item i of mylist is searchitem then
return i
exit repeat
end if
end repeat
end get_loc
or, if you have consecutive numbers from 1, this is easier and faster
set searchitem to "B"
set mylist to {"ABC"}
considering case
display dialog searchitem & " is at position " & (offset of searchitem in mylist) & " in the list!"
end considering
set mainList to {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}
display dialog "Input String:" default answer "XYZ" buttons {"OK"} default button 1
set tempList to every character of text returned of the result
set ItemA to item 1 of tempList
set ItemB to item 2 of tempList
set ItemC to item 3 of tempList
set ItemD to item 4 of tempList
set posA to my get_loc(ItemA, mainList)
set posB to my get_loc(ItemB, mainList)
set posC to my get_loc(ItemC, mainList)
set posD to my get_loc(ItemC, mainList)
--Some further code
on get_loc(searchitem, mylist)
considering case
return offset of searchitem in mylist
end considering
end get_loc
Thanks to everyone for their help as I have learnt a few options along the way.
I apologize but in your late message, mainList is not a list but a string.
Here is a slightly modified version of the code searching in a true list.
property Liste : {"alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"}
set theLoc to my get_loc("omicron", my Liste)
log theLoc
set theLoc to my get_loc("omIcron", my Liste)
log theLoc
on get_loc(searchitem, mylist)
considering case
repeat with i from 1 to count of mylist
if (item i of mylist) as text is searchitem then return i (* if match *)
end repeat
end considering
return 0 (* if don't match *)
end get_loc
Yvan KOENIG (from FRANCE mardi 6 mai 2008 18:04:07)