• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
sort a list and remove duplicate
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

sort a list and remove duplicate


  • Subject: sort a list and remove duplicate
  • From: Yvan KOENIG <email@hidden>
  • Date: Fri, 22 May 2015 16:16:43 +0200

Hello

I reproduce here an exchange which I had a few hours ago in a list dedicated to asobjcEx.

part 1: my original message:

Hello

Here is a sample of a code which I uses often.

Is it a way to trigger the makeUnique part using only BridgePlus?


use framework "Foundation"
use BridgePlus : script "BridgePlus"

set someList to {"itemZ", "itemB", "itemA", "itemB", "itemZ"}

# Before BridgePlus I used :
set aList to my sortAndRemoveDuplicates:someList
--> {"itemA", "itemB", "itemZ"}


# Is it a better way than that to achieve the same goal with Bridge ?

set anArray to Cocoaify someList
set anArray to anArray's sortedArrayUsingSelector:"compare:"
set aList to ASify from anArray
--> {"itemA", "itemB", "itemB", "itemZ", "itemZ"}
set aList to my makeUnique:aList
--> {"itemA", "itemB", "itemZ"}


#=====

on makeUnique:theList
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects() as list
end makeUnique:

#=====

on sortAndRemoveDuplicates:theList
set anArray to current application's NSArray's arrayWithArray:theList
set theList to (anArray's sortedArrayUsingSelector:"compare:") as list
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects() as list
end sortAndRemoveDuplicates:

#=====


Thanks in advance.


part 2 : Shane STANLEY's answer 1

There are a couple of ways of approaching it. One is to keep all the Cocoa-AS bridging in the handlers. So:

use script "BridgePlus"

set someList to {"itemZ", "itemB", "itemA", "itemB", "itemZ"}

set aList to my sortAndRemoveDuplicates:someList

on makeUnique:theList
set theSet to current application's NSOrderedSet's orderedSetWithArray:(Cocoaify theList)
return ASify from (theSet's allObjects())
end makeUnique:

on sortAndRemoveDuplicates:theList
set anArray to Cocoaify theList
set theList to (anArray's sortedArrayUsingSelector:"compare:")
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return ASify from (theSet's allObjects())
end sortAndRemoveDuplicates:

In that way, you just pass AS lists, and get lists back. The alternative is to keep the conversion outside the handlers unless required:

use script "BridgePlus"

set someList to {"itemZ", "itemB", "itemA", "itemB", "itemZ"}

set aList to ASify from (my sortAndRemoveDuplicates:(Cocoaify someList))

on makeUnique:theList
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects()
end makeUnique:

on sortAndRemoveDuplicates:theList
try -- in case it's already a Cocoa object
set theList to Cocoaify theList
end try
set theList to (theList's sortedArrayUsingSelector:"compare:")
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects()
end sortAndRemoveDuplicates:

The advantage of the former is that you do all the work in the handlers, which you write and forget. The advantage of the latter is that, if you're dealing with lots of stuff and you want the best performance, you control when the conversion happens.

The thing is, when you, say, pass a long list of things to be sorted using sortedArrayUsingSelector:, most of the time is actually spent converting from AS to Cocoa and back again -- the actual sorting generally takes only a fraction of the time. And the discrepancy gets greater with longer lists. So if you are going to call another Cocoa method using the result, you actually save a bit of time if you don't do the conversion back to AS and then back to Cocoa again. When that actually matters is something you have to decide -- I suspect only when the lists are very long.

In your original handler:

on sortAndRemoveDuplicates:theList
set anArray to current application's NSArray's arrayWithArray:theList
set theList to (anArray's sortedArrayUsingSelector:"compare:") as list
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects() as list
end sortAndRemoveDuplicates:

That first "at list" is an example: you have converted it from an array to a list, only to pass it to a method that will have to turn it back to an array. Will you notice the difference? Unless the lists are very big, probably not.

So I'd go for the first method, except where you know you want to squeeze out every ounce of performance.


part 3 : Shane's answer 2

PS: I'm happy to answer questions here, but this sort of thing would probably be better asked on the general AS mailing list.


part 4 : Shane's answer 3

So I'd go for the first method, except where you know you want to squeeze out every ounce of performance.

And FWIW, the first is almost twice as fast in a simple test of your sample here. That's because of the try in the second case, which uses up a bit of time. I probably should have used Cocoaify for and avoided the need.


part 5 : my auxiliary question

After a longer practice of ASObjC Expander, I have the impression that my original handler :

#=====

on sortAndRemoveDuplicates:theList
set anArray to current application's NSArray's arrayWithArray:theList
set theList to (anArray's sortedArrayUsingSelector:"compare:") as list
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects() as list
end sortAndRemoveDuplicates:

may be enhanced by dropping a list conversion.

#=====

on sortAndRemoveDuplicates:theList
set anArray to current application's NSArray's arrayWithArray:theList
set theList to (anArray's sortedArrayUsingSelector:"compare:") -- as list
set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
return theSet's allObjects() as list
end sortAndRemoveDuplicates:


It works but I want Shane's advice because maybe I missed a collateral effect.
In other scripts I made some changes of this kind. Most of the time it works flawlessly but in some of them the script run once but if I call it a second time the Scripts Editor quits.
In the example above, I was able to cal the handler more than 10 times with no problem.

Yvan KOENIG (VALLAURIS, France) vendredi 22 mai 2015 16:15:25










 _______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden

  • Follow-Ups:
    • Re: sort a list and remove duplicate
      • From: Yvan KOENIG <email@hidden>
  • Prev by Date: Re: [ANN] BridgePlus script library
  • Next by Date: Re: sort a list and remove duplicate
  • Previous by thread: Folder icon arrangement
  • Next by thread: Re: sort a list and remove duplicate
  • Index(es):
    • Date
    • Thread