short name for choose from list

I feel like I’ve seen how to do this before, but I’m blanking due to lack of coffee at the moment.
If I have a list of email addresses, can I easily associate those addresses to a “short name” which would be used for “choose from list” portion?


set theUsers to {"John", "Howard", "Han"}
set theAssignees to {"John.Smith@company.com", "Howard.Hughes@company.com", "Han.Solo@star.wars"}


set theAssign to choose from list theUsers


Basically, I want “Josh, Howard and Han” to be the choices in the list. But I want the variable theAssign to be set to the full email address. I know I could do a series of if…else if statements to force it, but thought there might be a more elegant solution using an array of the two lists, or something.

Thanks!

Hi,

two suggestions:

  1. Create the list with an index prefix
{"1 John", "2 Howard", "3 Han"}

then get the first word of the result, coerce it to integer and get the address by that index

  1. Use a handler to get the index of a given item in a given list
set theUsers to {"John", "Howard", "Han"}
set theAssignees to {"John.Smith@company.com", "Howard.Hughes@company.com", "Han.Solo@star.wars"}

set theAssign to choose from list theUsers
if theAssign is false then return
set assignIndex to indexOfItem(item 1 of theAssign, theUsers)
set theAddress to item assignIndex of theAssignees

on indexOfItem(theItem, theList)
	repeat with i from 1 to count theList
		if item i of theList is theItem then return i
	end repeat
end indexOfItem

Here is other (the fastest solution). The OP should add match list, then run this code:


set theUsers to {"John", "Howard", "Han"}
set theAssignees to {"John.Smith@company.com", "Howard.Hughes@company.com", "Han.Solo@star.wars"}
set matchList to {"-1-", "-2-", "-3-"}

try
	set theChoice to item 1 of (choose from list theUsers)
on error
	return
end try


set thePosition to my indexOf(theChoice, theUsers)
set theAssign to (get item thePosition of theAssignees)

on indexOf(theItem, theList)
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to return
	set theList to return & theList & return
	set AppleScript's text item delimiters to oTIDs
	try
		-1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in theList) of theList)))
	on error
		0
	end try
end indexOf

NOTE: it is faster, because you create matchList once, then choose name multiple times.

Here is my version of the handler “indexOf”


on indexOf(theItem, theList)
	local tid, tempList
	set tid to text item delimiters
	set text item delimiters to return
	set tempList to theList as text
	set text item delimiters to tid
	try
		return count paragraphs of text 1 thru (offset of theItem in tempList) of tempList
	on error
		return 0
	end try
end indexOf

Fredrik71,

I can certainly see that you are pretty good at programming, maybe better than me, but you don’t need to suggest this StefanK’s repeat loop approach over and over again. This is what I’m trying to rid the user of.

robertfern,

your handler and mine are twins because they are one and the same.

And you, KniazidisR, don’t need to start replying to old threads again. This one dates from February 2018 and the OP received a perfectly good answer then. They’re unlikely still to be watching it in case you happen to come up with an answer that others have thought of before.

You may not tell others what they can and cannot post here.

KniazidisR

Yours seems to do unnecessary things like manually concatenateing returns at front and rear of list
then subtract 1 from answer (WHY)

Mine also doesn’t change the passed list. Since AppleScript passes list by reference, this could be problematic. Mine copies contents of list as text to temp variable

So no, yours and mine are not the same.

Just my opinion

You could use a record or dictionary instead of two arrays and repeat loops.


use scripting additions
use framework "Foundation"

set NSDictionary to current application's class "NSDictionary"

set theAssigneesRecord to {John:"John.Smith@company.com", Howard:"Howard.Hughes@company.com", Han:"Han.Solo@star.wars"} as record
set theAssigneesDictionary to NSDictionary's dictionaryWithDictionary:theAssigneesRecord
set theAssigneesDictKeys to theAssigneesDictionary's allKeys() as list

try
	set theChosenAssignee to item 1 of (choose from list theAssigneesDictKeys)
on error
	return
end try

set theAssigneesEmail to (theAssigneesDictionary's valueForKey:theChosenAssignee) as text

Just another option

Regards Mark

Fredrick71 wrote

I’m not sure if it would be significantly faster, as it’s still AppleScript at the end of the day.
So the awnser to that would be try testing it.

My guess would be that because it’s using the NSDictionary class, it should be faster than AppleScript lists and repeat loops.
But I’m not sure it would be noticeably different.
I changed all of my projects and applets over to Swift applications and utilities some time ago, which are ten times faster, but I wouldn’t know if Foundation classes like NSArray or NSDictionary perform much quicker than AppleScript Lists and Records.

Sorry for not helping much with that question.

Sometimes it’s not just a performance thing, but a preference thing.
To me the record or dictionary method looks and feels less messy and more concise.
And why use a loop if you don’t need to ?

But were all different, and what looks and feels good to me, might not to others.

Mark

Hi robertfern.

Bracketing both the search string and the return-delimited source string with returns ensures that the delimitation occurs in the right place, not at some other point which happens to have the same characters as the bare search string. The returns at each end of the source string are needed for when the return-bracketed search string occurs at the beginning or the end of it.

For a big list ( a thousand or more) it possibly will be – but who’s going to use choose from list with that many entries?

That said, it can probably be simplified a little:

And if you’re putting up a dialog, which halts a script, a one-off hit of a fraction of a second is probably just noise in the overall scheme of things.

AsObjC-solution proposed by Mark FX is the only worthy competitor to my plain-AppleScript solution in this topic. Everything else is pouring water from empty to empty and back. I don’t mean StefanK. His solution is the first working solution in this thread, although I don’t find it the most efficient one. Why I was looking for something else. I didn’t want to offend anyone here.

Then I’d suggest you stop passing judgment on others’ posts. Post your own versions by all means, but please don’t set yourself up as some kind of modern Solomon.

Hi, Shane,

The exact repetition of the solution already proposed above seemed to me an act hostile to me. Or was it really done on purpose? Then I have the right to defend myself.

You have the right to complain to either Mark or myself if you feel any script posted here is somehow an act hostile to yourself. You have a right to discuss the relative merits of various approaches and to defend your own if someone else criticises it. You don’t have a right to set yourself up, as Shane said, “as some kind of modern Solomon”.

Other people post their solutions here in good faith in order to contribute to the discussion, not to attack you. It’s not for you to judge publicly whether their efforts are worthy competitors to your own.

This topic is now closed.