Applescript Lists

Hello all from a newbie
I am working on my first script and wondered if there is a way to get the position of an item within a list.

Sort of like…
Set MyList to {'x", “y”, “z”}
Set MyItem to position of “y” in MyList

Basically, I am trying to convert alphabets to equivalent numbers and vice versa.

Thanks

Hi Dayo,

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

Thanks a mil!

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

Thanks Adam

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

Thanks Stefan

I have simplified my code to something like this…


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.

Hello

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)