Re: Sort a List with Integers & Letters
Re: Sort a List with Integers & Letters
- Subject: Re: Sort a List with Integers & Letters
- From: "Nigel Garvey" <email@hidden>
- Date: Wed, 4 Apr 2007 09:56:42 +0100
I wrote on Tue, 3 Apr 2007 23:58:10 +0100:
>The script below uses the customisable version of Arthur's and my qsort,
>with a custom script object that sorts lists in parallel, based on the
>ModelNumber of each item. Since this has to work with pre-Tiger systems,
>without the 'numeric strings' attribute, the list is duplicated and the
>ModelNumbers in the duplicate are padded with leading zeros so that their
>leading numerics are all 10 digits wide. (Add more zeros if necessary.) The
>duplicate is then sorted and the sort moves are paralleled in the original.
>Not pretty, but it works.
It's occurred to me this morning that the duplicate list doesn't need to
contain records, only the doctored ModelNumber strings - which makes the
sort process _slightly_ simpler and more efficient:
on CustomQsort(theList, l, r, compObj)
script o
property cutoff : 10
property p : theList
on qsrt(l, r)
set i to l
set j to r
set v to my p's item ((l + r) div 2)
repeat while (j > i)
set u to my p's item i
repeat while (compObj's isLess(u, v))
set i to i + 1
set u to my p's item i
end repeat
set w to my p's item j
repeat while (compObj's isGreater(w, v))
set j to j - 1
set w to my p's item j
end repeat
if (i > j) then
else
set my p's item i to w
set my p's item j to u
compObj's swap(i, j)
set i to i + 1
set j to j - 1
end if
end repeat
if (j - l < cutoff) then
else
qsrt(l, j)
end if
if (r - i < cutoff) then
else
qsrt(i, r)
end if
end qsrt
on isrt(l, r)
set x to l
set z to l + cutoff - 1
if (z > r) then set z to r
set v to my p's item x
repeat with y from (x + 1) to z
if (compObj's isLess(my p's item y, v)) then
set x to y
set v to my p's item y
end if
end repeat
tell my p's item l
set my p's item l to v
set my p's item x to it
end tell
compObj's swap(l, x)
set u to my p's item (l + 1)
repeat with i from (l + 2) to r
set v to my p's item i
if (compObj's isLess(v, u)) then
set my p's item i to u
repeat with j from (i - 2) to l by -1
if (compObj's isLess(v, my p's item j)) then
set my p's item (j + 1) to my p's item j
else
set my p's item (j + 1) to v
compObj's shift(j + 1, i)
exit repeat
end if
end repeat
else
set u to v
end if
end repeat
end isrt
end script
set listLen to (count theList)
if (listLen > 1) then
if (l < 0) then set l to listLen + l + 1
if (r < 0) then set r to listLen + r + 1
if (r = l) then
else
if (l > r) then
set temp to l
set l to r
set r to temp
end if
if (r - l < o's cutoff) then
else
o's qsrt(l, r)
end if
o's isrt(l, r)
end if
end if
return -- nothing
end CustomQsort
script parallelSort
property slaveList : missing value
on isLess(a, b)
(a < b)
end isLess
on isGreater(a, b)
(a > b)
end isGreater
on swap(a, b)
tell item a of my slaveList
set item a of my slaveList to item b of my slaveList
set item b of my slaveList to it
end tell
end swap
on shift(a, b)
tell item b of my slaveList
repeat with i from b - 1 to a by -1
set item (i + 1) of my slaveList to item i of my slaveList
end repeat
set item a of my slaveList to it
end tell
end shift
end script
on convertedMNStrings(recordList)
script o
property stringList : {}
end script
copy recordList to o's stringList
set digits to "0123456789"
set zeros to "0000000000"
set z to (count zeros)
considering case
repeat with i from 1 to (count recordList)
set mn to ModelNumber of item i of o's stringList
set c to (count mn)
repeat until (character c of mn is in digits)
set c to c - 1
end repeat
set item i of o's stringList to text 1 thru (z - c) of zeros & mn
end repeat
end considering
return o's stringList
end convertedMNStrings
set theList to {{ModelNumber:"1610G", ModelName:"Gold Plate"},
{ModelNumber:"121ZB", ModelName:"Zip Guard"}, {ModelNumber:"114",
ModelName:"White Matte"}} & ¬
{{ModelNumber:"13", ModelName:"Sterling Silver"},
{ModelNumber:"21124", ModelName:"Blueberry"}, {ModelNumber:"121FB",
ModelName:"Flat Bottom"}}
set list2 to convertedMNStrings(theList)
set parallelSort's slaveList to theList
CustomQsort(list2, 1, -1, parallelSort)
theList
--> {{ModelNumber:"13", ModelName:"Sterling Silver"},
{ModelNumber:"114", ModelName:"White Matte"}, {ModelNumber:"121FB",
ModelName:"Flat Bottom"}, {ModelNumber:"121ZB", ModelName:"Zip Guard"},
{ModelNumber:"1610G", ModelName:"Gold Plate"}, {ModelNumber:"21124",
ModelName:"Blueberry"}}
NG
_______________________________________________
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