iTunes: remove duplicates from a list

I’m trying to write a portion of a script that will let me put all the albums of an artist in a list. If you simply say to get the album of every track of artist X then you end up with an item for each track. So I found this bit of code:

tell application "iTunes"
    set myList to get artist of every track of library playlist 1
end tell
set t1 to the ticks
set r to remove_duplicates(myList)
set t2 to the ticks
display dialog (t2 - t1)
return r
-- 
on remove_duplicates(the_list)
    script S
        property list_ref : the_list
    end script
    set return_list to {}
    repeat with an_item in list_ref of S
        if return_list does not contain an_item then set end of return_list to ¬
            (contents of an_item)
    end repeat
    return return_list
end remove_duplicates

I got it from this thread: http://macscripter.net/viewtopic.php?id=16378

Fine and good. However, I want to have a list of four artists that this repeats through each artist. So, I came up with this:


set alwaysArtists to {"Rush", "Pink Floyd", "Low", "R.E.M."}
repeat with theArtist in alwaysArtists
	
	tell application "iTunes"
		set myList to get (album of every track of library playlist 1 whose artist is theArtist)
	end tell
	
	--set eachAlbum to removeDuplicates(myList)
	--return eachAlbum
end repeat

on removeDuplicates(myList)
	script S
		property list_ref : myList
	end script
	set return_list to {}
	repeat with an_item in list_ref of S
		if return_list does not contain an_item then set end of return_list to (contents of an_item)
	end repeat
	return return_list
end removeDuplicates

With the call on the subroutine commented out, this should work fine (assuming you have those artists in your Library, natch). When I scan the results, I see that it generated a list of the album of each track and repeated that for each artist. However, when I uncomment the subroutine call, it only goes through the first item.

Any help with this?

This doesn’t work the way you think…
set eachAlbum to removeDuplicates(myList)

Basically every time through the repeat loop you clear out the previous list and create a new list with the albums of an artist… so you end up with only a list with the albums of the last artist i.e. REM. In order to compile them all you have to add the lists together instead of clearing out the list each time. As such you need something like this.

set alwaysArtists to {"Rush", "Pink Floyd", "Low", "R.E.M."}

set eachAlbum to {}
repeat with theArtist in alwaysArtists
	try
		tell application "iTunes"
			set myList to get (album of every track of library playlist 1 whose artist is theArtist)
		end tell
		
		set end of eachAlbum to removeDuplicates(myList)
	end try
end repeat
return eachAlbum

on removeDuplicates(myList)
	script S
		property list_ref : myList
	end script
	set return_list to {}
	repeat with an_item in list_ref of S
		if return_list does not contain an_item then set end of return_list to (contents of an_item)
	end repeat
	return return_list
end removeDuplicates

This gives you a list with 4 lists inside of it. Each internal list contains the unique albums for each of your 4 artists. The try block is there in case iTunes doesn’t find any albums for one of the artists.

That’s because you had the return statement inside of the repeat loop. As soon as the script hits the return command it stops the script and returns whatever… even if you are in a repeat loop. So you were stopping it yourself during the first iteration of the repeat loop.

Actually, I want it to handle each list separately. From the list of one artist’s album I’m going to have it grab two random items and then add all tracks from those albums to a playlist and only then move on to the next artist. However, taking the “return” solves it exactly! I didn’t know that a return would dump you out of a repeat; I thought it would give you the results and then go back into the loop.

Problem solved (at least this one).
So, thanks very much!

You can. Your results will look like this…
{{a,b,c}, {d,e,f,g,h}, {i,k}, {k}}

So notice you have a list with 4 lists in it. So you can repeat through the outer list and then in the repeat loop you have only the albums for one artist.
repeat with oneArtistsAlbums in eachAlbum
– do something with this set of albums
end

I thought that was how it was supposed to work, but when I was playing with that, it was adding each new result to the master list. So I was getting: {a,b,c} then {a,b,c,d,e,f} then {a,b,c,d,e,f,g,h,i,j}

Obviously I was doing something wrong. Thanks, I’ll give that a try.