Add to list

I tried:

set thelist to the list and add thething to end of thelist

If it’s lists you’re talking about you can.

A: concatenate and assign:

set the |list| to the |list| & new_item

B: copy to the end of the list:

copy new_item to the end of the |list|

(B) is more efficient than (A), but both work nicely. Note that (B) doesn’t work with records (those {label:value,.} things). You have to use something like (A).

No. (B) is (almost?) always more efficient than (A), and it DOES work with adding records to the end of the list. Note, you may be confused by the fact that the result of the “copy” command returns the thing copied to the end, not the list to which it was copied, but the list itself actually is still a list with the new thing at the end.

Example:

set someList to {"a"}

copy {firstName:"John", lastName:"Smith"} to end of someList

return someList
--> RESULT: {"a", {firstName:"John", lastName:"Smith"}}

But, if you just get the result of the “copy” line (which you should not do):

set someList to {"a"}

copy {firstName:"John", lastName:"Smith"} to end of someList

return result
--> RESULT: {firstName:"John", lastName:"Smith"}

In the first (correct) example, you are modifying someList, and then looking at what it contains. In the second example, you are merely asking what you were just doing. The result of the copy line is almost never useful. It is what it operates on (the list variable) that is interesting and what you should use.

Copying to the end of a list is much quicker than setting a list to itself & what you want to add. But the quickest way is to set the end of a list to something:

set myList to {"a", "b"}
set end of myList to "c"

There used to be a post that gave a good example of the time saving over on the Apple AS Discussion Boards, but it looks like it’s gone now. I’ll try to recreate it.

A)

set myList to {}
set t0 to (current date)

repeat with x from 1 to 10000
	set myList to myList & x
end repeat

set t1 to (current date)
set theTime to (t1 - t0)
display dialog (theTime as string) & " seconds"

95 seconds for me.

B)

set myList to {}
set t0 to (current date)

repeat with x from 1 to 10000
	copy x to end of myList
end repeat

set t1 to (current date)
set theTime to (t1 - t0)
display dialog (theTime as string) & " seconds"

82 seconds for me.

C)

set myList to {}
set t0 to (current date)

repeat with x from 1 to 10000
	set end of myList to x
end repeat

set t1 to (current date)
set theTime to (t1 - t0)
display dialog (theTime as string) & " seconds"

One second!

And yes, they’re all doing the exact same thing.

I meant with extending records, not concatenating records to lists:

set the end of {|name|:"John Doe"}to {age:42} -- error!!! can't add labels to a record (and they aren't ordered so there is no "end")

In that case one would have to do:

{|name|:"John Doe"} & {age:42} -- result: {|name|:"John Doe",age:42}

Sorry for the confusion.

Oh. Of course - as you noted, records do not have ends to copy things to or change.

Well, I suppose, to be pedantic, they’re not doing the same thing at all! (As has been described above.) But they do all end up with the variable myList having a list value containing all the integers from 1 to 10000.

The concatenation method is the slowest because there’s so much to do. You can only concatenate like to like, so when the integer x is concatenated to the list myList, it’s automatically coerced to a list itself first, and the concatenation that actually takes place is:

set myList to myList & {x}

Each concatenation involves the creation of a third list containing the items from the original lists. The variable myList is then reset to point to the new list and the other two lists are quietly forgotten. A 10000-concatenation repeat thus generates 20000 new lists, the last of which is the final result.

The two ‘end of myList’ methods both append an item to the end of the original list. If the value of x is, say, 4, the ‘set’ command appends a pointer to that same instance of 4 to the end of the list. The ‘copy’ command, on the other hand, creates a duplicate instance of the value and appends a pointer to that.

I hope you like technicalities. :slight_smile: