I have absolutely no idea what is going on here…
I’m trying to sort a list of lists by the first item of each item. It seems like a pretty straight forward operation, but I’m running into a very strange issue. The original list “a1” seems to change while going through the repeat loop, and thus returns overlapping values. I’ve condensed the code here and inserted some dummy values. Does anyone have any idea what is going on here? Thank you for your time.
set a1 to {{"02", "words1"}, {"03", "words2"}, {"01", "words3"}, {"05", "words4"}, {"04", "words5"}}
aSort(a1)
on aSort(a1)
set a2 to a1
repeat with i from 1 to (count a2)
set indexNum to ((item 1 of item i) of a1) as integer
set (item indexNum of a2) to item i of a1
end repeat
return a2
end aSort
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)
danger:
Your routine is simply doing replacement, not sorting. This modification will show you each iteration in a TextEdit file:
set txt to ""
global txt
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set a1 to {{"02", "words1"}, {"03", "words2"}, {"01", "words3"}, {"05", "words4"}, {"04", "words5"}}
aSort(a1)
set AppleScript's text item delimiters to astid
tell application "TextEdit" to make new document with properties {text:txt}
on aSort(a1)
set a2 to a1
repeat with i from 1 to (count a2)
set indexNum to ((item 1 of item i) of a1) as integer
set (item indexNum of a2) to item i of a1
set txt to txt & (a2 as string) & return & return
end repeat
return a2
end aSort
For sorting, I prefer the bubblesort, but if you search around this forum will find a few other methods as well:
set a1 to {{"02", "words1"}, {"03", "words2"}, {"01", "words3"}, {"05", "words4"}, {"04", "words5"}}
bubblesort(a1)
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if (item 1 of item j) > (item 1 of item (j + 1)) then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end bubblesort
-->{{"01", "words3"}, {"02", "words1"}, {"03", "words2"}, {"04", "words5"}, {"05", "words4"}}
Good luck,
Hey Craig, thanks for the reply. The bubblesort works perfectly for my need. I really appreciate it. I thought that the replacement method would work fine since all I was trying to do was order a list after it was created. Still don’t get why that wasn’t working, but at least now I have something that does!
Glad it worked. The issue with your logic is simply that by replacing say, item 2 of a list with say item 4 of a list is that the previous item 2 is now gone. So, although logical, in practical terms, it cannot work, unless you preserve that original item 2 somehow for later insertion in its proper place. The bubblesort routine simply swaps items back and forth until all are sorted in whichever order the user desires. In that fashion, no data is replaced (and then lost), its position in the list is simply changed with its neighbor. This modification of the bubblesort script will present another TextEdit file to show how these iterations occur. It may be helpful to print it out and go line by line through the script to get a handle on how the logic works:
global txt
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set a1 to {{"02", "words1"}, {"03", "words2"}, {"01", "words3"}, {"05", "words4"}, {"04", "words5"}}
set txt to (a1 as string) & return & return
bubblesort(a1)
set AppleScript's text item delimiters to astid
tell application "TextEdit" to make new document with properties {text:txt}
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if (item 1 of item j) > (item 1 of item (j + 1)) then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
set txt to txt & (array as string) & return & return
end if
end tell
end repeat
end repeat
return array
end bubblesort
-->{{"01", "words3"}, {"02", "words1"}, {"03", "words2"}, {"04", "words5"}, {"05", "words4"}}
Good luck with your scripting,