Is there any way to get the position of an item in a list without looping?
For example…
set theList to {"test1","test2","test3","test4"}
I would like to find “test3” in this list and get a result of 3. Is there a way of doing this without looping through each item and checking it individually?
A repeat loop is still probably the best way to get the index of an item in a short list:
to getIndex of i from l
repeat with n from 1 to count l
if l's item n is i then return n
end repeat
0
end getIndex
set theList to {"test1", "test2", "test3", "test4"}
set theItem to "test3"
getIndex of theItem from theList
--> 3
To get the index of an item in a long list of strings, you could speed up the operation by using text item delimiters:
to getIndex of i from l
set tid to text item delimiters
set text item delimiters to return
set l to return & l & return
set text item delimiters to return & i & return
tell l's text items to if (count) is 1 then
set i to 0
else
set i to count item 1's paragraphs
end if
set text item delimiters to tid
i
end getIndex
set theList to {"test1", "test2", "test3", "test4"}
set theItem to "test3"
getIndex of theItem from theList
--> 3
I am playing around with a similar issue. I have a list of names of AppleWorks database fields, and I need to obtain the number in the list for the search function of that field. I modified a single line of your very neat script:
to getIndex of i from l
repeat with n from 1 to count l
if l's item n is i then return n
end repeat
0
end getIndex
set theList to {"test1", "test2", "test3", "test4"}
set theItem to choose from list theList--MODIFED LINE
getIndex of theItem from theList
--> 0--NEW RESULT
I had the same problem in my script; I cannot find a way to compare string data for an exact match. I got the function to work using the command [contains], but I am curious if there is a way to compare two strings for an exact match?
to getIndex of i from l
repeat with n from 1 to count l
if l's item n is i then return n
end repeat
0
end getIndex
set theList to {"test1", "test2", "test3", "test4"}
set theItem to (choose from list theList) as string
getIndex of theItem from theList
--> 3
Apparently, when an item is chosen from a list, it must be coerced back into a string to compared to the original string.
‘choose from list’ returns a list of the item(s) chosen. Pedantically, you should extract the item from the returned list rather than coerce the list to string:
set theItem to item 1 of (choose from list theList)
But coercion is OK if you know that only one item will be chosen and that it’ll be a string.
Thanks, Qwerty. I forgot to add yesterday that, unlike the other ‘choose …’ commands, ‘choose from list’ returns ‘false’ when the Cancel button’s clicked. (I think this is for historical reasons, dating back to when many of what are now the StandardAdditions commands were separate OSAXen written by different people.) Scripts thus have to be prepared to get back ‘false’ instead of a list.
The other ‘choose …’ commands automatically generate a “User canceled.” error when the “Cancel” button (or the equivalent in the local language) is clicked. This stops a script immediately without the scripter having to write exit code. The same error can be scripted as a response to ‘choose folder’:
set theList to {"test1", "test2", "test3", "test4"}
set theChoice to (choose from list theList)
if (theChoice is false) then error number -128 -- "User canceled."
set theItem to item 1 of theChoice
I have a very simple list of data in a .txt file (two columns with less than twenty rows of data). I want to select from the data in Column A (my select from list) and match with the list in Column B. i.e., return the value in Column B that corresponds to the selected value in column A. Then execute a separate script utilizing the returned value from Column B in the list of data.
My selection code works fine, but can’t get the loop routine to return anything other than zero (0). Not sure what I am doing wrong.
set theData to (path to desktop as text) & "TextFile.txt" as string
tell application "Microsoft Excel"
open theData
set lastCell to first row index of (find column 1 what "" look in values look at whole)
set Names to the value of the range ("A1:A" & (lastCell - 1))
set Addresses to the value of the range ("B1:B" & (lastCell - 1))
close workbook 1 without saving
end tell
set SelectedName to choose from list Names with prompt "Select a Name"
to getIndex of i from l
repeat with n from 1 to count l
if l's item n is i then return n
end repeat
0
end getIndex
set theList to Names as list
set theItem to SelectedName
getIndex of theItem from theList