Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Jon Trepte

macrumors newbie
Original poster
Sep 17, 2014
4
0
I have the following code to compare 2 strings
Code:
set s1 to "A.P.E."
set s2 to "A.P.E_"
log s1
log s2

set a1 to ASCII number "."
set a2 to ASCII number "_"

log s1 < s2
considering case
	log s1 < s2
	log s1 is less than s2
end considering

and I get the following strange results
(*A.P.E.*)
(*A.P.E_*)
tell current application
	ASCII number "."
		--> 46
	ASCII number "_"
		--> 95
	(*false*)
	(*false*)
	(*false*)
end tell
can anybody out there please tell me what is going on here as I think s1 should be less than s2 as they differ in the 6th char (46 and 95) and I think 46 is less than 95. Maybe I'm going senile!!!!
 
Last edited by a moderator:

chown33

Moderator
Staff member
Aug 9, 2009
10,654
8,244
A sea of green
You're assuming that AppleScript uses ASCII collation order for strings. It doesn't.

It uses the language-specific collation order for your currently selected language. If you've selected English as your primary language, then it uses that collation order (aka "sort order"). You might think that English collation order would be the same as ASCII but it isn't.

I googled the search terms applescript collation order. The two of the top results (not necessarily in this order) are:
https://developer.apple.com/library...ScriptLangGuide/reference/ASLR_operators.html
http://lists.apple.com/archives/applescript-users/2008/Oct/msg00340.html

The first is a reference that explains how AppleScript collates (sorts or compares) strings (text). The second is a post to an AppleScript mailing list that shows the actual results for the English language collation order. In particular, note where '_' and '.' are located.

If you need ASCII collation or comparison, you'll have to use something other than AppleScript's builtin operators. For suggestions, you'll first have to explain what you're trying to do, so we know what tools would be applicable.


I don't know of a reference that lists OS X's collation order for English, or any other language. If you really need to know what it is, you should write a program that produces it.

If you want to try an experiment, set the "Order for sorted lists" in System Preferences to Hawaiian and observe the effect it has on the collation order for letters. For example, sort a Finder window by name after choosing Hawaiian.
http://en.wikipedia.org/wiki/Hawaiian_language#Orthography
 

Jon Trepte

macrumors newbie
Original poster
Sep 17, 2014
4
0
Hi chown33,
Firstly let me thank you for your time and effort.
OK here is what I'm trying to do. I have an iTunes library and I wish to put it on my NAS. However when I did I found that my NAS is case sensitive and iTunes could not find some 5,000 songs from 88,000. So I used find in terminal to give me a text file with every song listed in the Music folder. This appears to be sorted in some particular order, probably the one you suggested. Now what I needed to do was go through every song in the iTunes library and compare it's location to the one in finder. I needed to do a binary search on my list created from the file and this is where I noticed strange things happening. So what I need is a string comparison function that uses the same collation order as finder did to give the list of files. I hope this helps.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,654
8,244
A sea of green
Hi chown33,
Firstly let me thank you for your time and effort.
OK here is what I'm trying to do. I have an iTunes library and I wish to put it on my NAS. However when I did I found that my NAS is case sensitive and iTunes could not find some 5,000 songs from 88,000.

Some programs misbehave on case-sensitive file systems. iTunes may be one. Hard to say without knowing versions.

One solution is to create a disk-image on the NAS, format it HFS+ case-insensitive, and put the iTunes library there.


So I used find in terminal to give me a text file with every song listed in the Music folder.
The output of find uses the order that entries are stored in the directory, unless told otherwise (-s option). You didn't show the 'find' command, so I can't suggest anything other than generalized comments.

This appears to be sorted in some particular order, probably the one you suggested.
Nope. It's the order that HFS+ stores directory entries in. The details of the B-tree enetries for the catalog file are documented, and it's definitely NOT Finder's sorting order. It's not AppleScript's string comparison ordering, either.

If you assumed a sorted order, you made an error. If you're planning to do a binary search, it's mandatory that the list be collated in the same order as the string-comparison function you plan to search with. Close isn't good enough; the collation must be exactly the same.

The obvious solution here is to sort the list into the order needed.

Now what I needed to do was go through every song in the iTunes library and compare it's location to the one in finder.
Manually go through every song? Or with a program? What language is the program written in? I could assume AppleScript, but I could be wrong.

What is it's location "in finder"? Do you mean "in the output of the 'find' command", or do you mean "the sorted result in a Finder window"? I don't know whether you really mean "Finder" (which seems irrelevant) or whether that's a typo for "find" (because the list was produced by 'find').

I needed to do a binary search on my list created from the file and this is where I noticed strange things happening.
As noted above, the same collation order is mandatory.

So what I need is a string comparison function that uses the same collation order as finder did to give the list of files.
Again the ambiguous term "finder". You used "find", not "Finder", to produce the list, as far as I can tell. Accuracy is important in programming.

You also assumed that find's output is sorted in the same collation order that AppleScript's string comparison uses.

The obvious solution at this point, and with no other information, is to assume the list produced by 'find' (not "finder") isn't sorted at all. Sort the list in AppleScript, using AppleScript's own comparison operation, before using it for binary search.
 

Jon Trepte

macrumors newbie
Original poster
Sep 17, 2014
4
0
Once again many thanks for your reply.
I used find in terminal like this having chanced to the iTunes music folder
Code:
find . -type f > AllFiles.txt
and this gave me a list of all my files
I then used textedit to remove the file prefix "Music:"
and saved the file. The file seemed to be somewhat sorted but not in the same collation order as AppleScript.
As you suggest I will have to get a sort algorithm in AppleScript to sort my list.
Once I get this list sorted I was going to write an AppleScript that would go through every track in the iTunes library along the lines of

Code:
tell application "iTunes"
	activate
	
	set nCount to count tracks of playlist 1
	log nCount
	set nErr to 0
	
	repeat with i from 1 to nCount
		set aTrack to track i of playlist 1
		set loc to location of aTrack as string
		--		log "Loc " & loc
		set theTextItems to text items of loc
		--		try
		set theTextItems to items 5 thru -1 of theTextItems -- wipe the path prefix
		set newLoc to (theTextItems as string)
		--			log "New Loc " & newLoc
		
		set Idx to my BinarySearch(newLoc, myList)
		if Idx < 0 then
			set Idx to -Idx
			set iLoc to item Idx of myList
			set nErr to nErr + 1
			log "Not Found :" & "Idx " & Idx & " " & nErr
			log newLoc
			log iLoc
		end if
		--		on error
		--			log "Error:" & loc
		--		end try
	end repeat
	log "Errors : " & nErr
end tell

The binary search would use a case sensitive string comparison and when a match fails I was going to set the iTunes loc to the actual path of the song.
This code is not final as my binary search routine fails as the list is not sorted correctly.

What is it's location "in finder"? Do you mean "in the output of the 'find' command", or do you mean "the sorted result in a Finder window"? I don't know whether you really mean "Finder" (which seems irrelevant) or whether that's a typo for "find"
I did mean find in all cases, sorry for the confusion.
So now I will try to find a sort routine to sort my list of 88,000 odd strings. One or two I've tried simply crash with no meaningful error code. I'll keep looking and keep you posted.
Once again Thanks
Jon
 
Last edited by a moderator:

chown33

Moderator
Staff member
Aug 9, 2009
10,654
8,244
A sea of green
So now I will try to find a sort routine to sort my list of 88,000 odd strings. One or two I've tried simply crash with no meaningful error code. I'll keep looking and keep you posted.

If you know how to write binary search, you can write a binary insertion sort. This is an insertion sort, so the list is kept sorted and new items are inserted one by one. New additions start by doing a binary search. This identifies the index (position) where the item would be found if it were already inserted. That means it's also the index where the item should be inserted. Insert the item at that index, moving up all others, and the list now contains the new item at its correctly sorted location.
 

Jon Trepte

macrumors newbie
Original poster
Sep 17, 2014
4
0
Fixed it!!

Dear chown33,
Right I've fixed my library at last. As you may know I was trying to copy my iTunes library from an external USB(Apple) drive to my NAS(linux). What I did initially was to simply copy the iTunes folder from "Volumes/Music&Pics/iTunes/..." to "Volumes/music/iTunes/..." where music is a public mounded volume on my Synology NAS. Next I pointed iTunes to this new library and all seemed OK until I tried to play a few songs and got the message that the file could not be found. So I wrote an AppleScript program to list all the file locations iniTunes and save them to a file (88,000 tracks). It took a while!!
Went I opened the file i found that many of the tracks were still in the original location (5,00- or so) but most seemed to have been corrected by iTunes to point to the new location i.e. "Volumes/music/iTunes/iTunes Media/Music/..." but the bat tracks still had "Volumes/Music&Pics/iTunes/iTunes Media/Music/...". Im sure this had something to do with the fact that the NAS was case-sensitive but the USB drive was not. So I wrote the following code to try and fix the problem

Code:
tell application "iTunes"
	activate
	set AppleScript's text item delimiters to ":"
	set fixed indexing to true
	
	set nCount to count tracks of playlist 1
	log nCount
	set nBad to 0
	
	repeat with i from 1 to nCount
		set aTrack to track i of playlist 1
		set loc to location of aTrack as string
		if loc starts with "Music&Pics:" then
			log i & " " & loc
			
			set theTextItems to text items of loc
			set item 1 of theTextItems to "music"
			set loc to (theTextItems as string) as alias
			set location of aTrack to loc
			
			set nBad to nBad + 1
		end if
		if loc does not start with "music:" then -- double check
			log i & loc
		end if
	end repeat
	log nBad
end tell

It took a while but it seemed to fix the problems. I'm still not sure how iTunes fixed the case problems. This code is not quite right as it assumes the tracks start with "Music&Pics" (bad) or "music" (good). Anyway again many thanks for your help with this matter.
Kindes regards
Jon
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.