Allow user to select items to be eliminated using "choose from list"

Hello all! New Scripter in the forum! I’m also new to AppleScript but I’ve done a fair amount of reading and practices to have a decent grasp of the fundamental.

I’ve just learned that in AppleScript we don’t “delete” or “remove” items from a list. Instead we have to create a new list without the item. With that said, I was trying to make an interaction where user can pick from a list of items and it will present a new list without the item that was previously selected.

As an example, this is what I started. User can select one person to eliminate from a list of people and it repeats until everyone is eliminated.

set pplList to {"Bob", "Amy", "Tod", "Ivy", "Joy", "Sam"}
set i to length of pplList

repeat until i is 0
	choose from list pplList with prompt "Pick one person to eliminate:"
	set i to i - 1
end repeat

Obviously this would just run the choose list prompt 6 times with the same list of people each time.

My novice self know I have to construct a new list without the person user selected, so I’ll definitely need to use the result from the first choose from list like

Set removedPerson to result

Then make a new choose from list with the new list and make it repeat until all people are eliminated.

All of the similar posts I’ve seen are working with numbers and using items n through n. This seems to be a bit harder because we are working with random order that user defined. Also since the choose from list is in the repeat loop, the result from making a selection is an integer.

Thank you all for your education! :slight_smile:

Edit: Typos

Hi and welcome to MacScripter

here’s a thread that does what your after, try post #1

Thank you so much Budgie!!!

I’m sorry I must’ve not searched the right thing. Everything I was reading on this forum or other sites did directly address this situation. I will read into it!

Cheers :cool:

set pplList to {"Bob", "Amy", "Tod", "Ivy", "Joy", "Sam"}

repeat until pplList = {}
		set {choice} to (choose from list pplList with prompt ¬
				"Pick one person to eliminate:") & {null}
		if the choice = false then return 0
		repeat with them in pplList
				tell them to if its contents = choice ¬
						then set its contents to null
		end repeat
		set pplList to the strings in pplList
end repeat

The method I’ve employed here searches the items in the list and replaces all objects that match the choice made with null. Then we can retrieve all the string values from the list, which, of course, omits the null objects. After overwriting the variable with the new, filtered list, the loop begins anew.

Dang this is GENIUS!!! :open_mouth: Much much appreciated!!!
I didn’t know you can do “tell (a variable) to” also never thought you can make the selection null and put it back and let it just automatically be ignored.

I do have a question if you don’t mind, in this line

set [choice] to (choose from list pplList with prompt "Pick one person to eliminate:") & {null}

Why is “choice” contained in the brackets “[]” (or whatever the correct terminology is lol)? I tried removing it and it becomes an infinite repeat loop. So it’s required but I don’t understand the syntax here.

Thanks x 1000 :slight_smile:


I don’t understand what you described.
Here the code below behaves flawlessly.

set pplList to {"Bob", "Amy", "Tod", "Ivy", "Joy", "Sam"}
set choice to (choose from list pplList with prompt "Pick one person to eliminate:") & {null}
-- returns {"Ivy", null} or {false, null}

This said, I really don’t understand what is the need for the [ & {null} ] component.
I would use :

set pplList to {"Bob", "Amy", "Tod", "Ivy", "Joy", "Sam"}
set choice to choose from list pplList with prompt "Pick one person to eliminate." # returns a list or a boolean equal to false
if choice is false then error number -128
set choice to choice's item 1

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 18 avril 2019 21:58:22

The square brackets are, for all intents and purposes, used instead of curly braces to create list objects. It’s largely my personal preference, but strictly speaking, one should just stick to curly braces (I’ll edit my previous post accordingly).

To summarise what this line does, it’s important to realise that the selection returned by the choose from command will always be returned as a list, even if it contains just a single item, which is the case here. Therefore, if the user selects “Joy”, the value returned is {“Joy”}. If the user cancels, the value returned is the boolean unary value of false; this is not contained within a list.

Normally, one would cater for these different situations like so:

set choice to choose from list pplList with prompt "Pick one person to eliminate:"
if the choice = false then return 0
set choice to item 1 of the choice

All I’ve done is taken the first line and the third line, and combined them into a single command expression, taking steps to ensure it can deal with both a list object and a unary value reliably, without throwing an error.

When I set the variable choice to a value, but enclose its identifier inside a list, for reasons I can explain if you wish me to, it serves as a shorthand to get the first item of a list from the expression supplying the value to be assigned. So, in general:

set {x} to L

is equivalent in most cases to:

set x to item 1 of L

You may want to stick to using the more demonstrative syntax, which will be clearer to you in the beginning about what’s going on.

The {null} being concatenated to the result of the user’s selection is what prevents errors being thrown. Were it absent, and the user cancels, the value returned from the choose from command, namely false, doesn’t have an item 1. However, if we do this:

false & {x}

the resulting value is a list containing two items: {false, x}. Now retrieving its first item makes total sense. x can actually be whatever you like, so I typically choose null as a way to signify its lack of significance, serving only as a placeholder.

If you have any other queries, or need something clarified, feel free to ask.

It is, of course, a very good and somewhat interesting solution, and it works. Only it confuses a little.

For example, 1) if choice is false, it would be more logical to return the edited list, and not 0. 2) You can avoid adding the null in the dialog. This is simply not necessary and confuses users. 3) the strings in pplList is well written. You can use text of pplList as well. 4) Makes sense to name the “Cancel” in this case “Exit list editing”. 5) When finding the match in the if block, we can exit repeat immediately.

set pplList to {"Bob", "Amy", "Tod", "Ivy", "Joy", "Sam"}

repeat until pplList = {}
	set choice to choose from list pplList with prompt ¬
		"Pick one item to eliminate:" cancel button name "Exit list editing"
	if the choice = false then return pplList
	set choice to item 1 of choice
	repeat with them in pplList
		if contents of them = choice then
			set contents of them to null
			exit repeat
		end if
	end repeat
	set pplList to text of pplList
end repeat