Sort List of iCal Events

I needed to sort a list in date order of ical events so i came up with these sort routines.

mind you it is slow(and gets even slower at an exponential rate) but i’ve put it through some paces and it seems to still work even on big lists it just takes a little while, it is lightning fast on say 20 events though.



on findLeastItem(lst)
	tell application "iCal"
		set theLeast to start date of item 1 of lst
		set theIndex to 1
		set iterater to 1
		repeat with i in lst
			if start date of i ≤ theLeast then
				set theLeast to start date of i
				set theIndex to iterater
			end if
			set iterater to iterater + 1
		end repeat
		
		return theIndex
	end tell
end findLeastItem

on removeItemAtIndex(lst, theIndex)
	set newList to {}
	set theLength to length of lst
	if theLength = 1 then
		set newList to {}
	else if theLength = theIndex then
		set newList to items 1 thru (theLength - 1) of lst
	else if theIndex = 1 then
		set newList to items 2 thru theLength of lst
	else
		set newList to items 1 thru (theIndex - 1) of lst & items (theIndex + 1) thru (theLength) of lst
	end if
	return newList
end removeItemAtIndex

on sortEvents(myList)
	set myNewList to {}
	repeat until length of myList = 0
		set leastIndex to findLeastItem(myList)
		set end of myNewList to item leastIndex of myList
		set myList to removeItemAtIndex(myList, leastIndex)
	end repeat
	return myNewList
end sortEvents

on getSecondsOfDays(Ndays)
	return ((current date) - (3600 * 24 * Ndays))
end getSecondsOfDays

--And to call this i use 
tell app "iCal"
   set weeksHours to every event of calendar "Hours" whose start date is greater than my getSecondsOfDays(6)
	set weeksHours to my sortEvents(weeksHours)
end tell

Model: MacBook Pro
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

One thing you can do is try replacing your sorting routine (bubble sort it looks like) with a quick sort:

on q_sort(theNumbers, leftVal, rightVal)
	
	set l_hold to leftVal
	set r_hold to rightVal
	set pivot to item leftVal of theNumbers
	set t to 0
	repeat while (leftVal < rightVal)
		
		repeat while (((item rightVal of theNumbers) ≥ pivot) and (leftVal < rightVal))
			set rightVal to (rightVal - 1)
		end repeat
		
		if (leftVal ≠ rightVal) then
			
			set t to (item leftVal of theNumbers)
			set item leftVal of theNumbers to (item rightVal of theNumbers)
			set item rightVal of theNumbers to t
			set leftVal to (leftVal + 1)
		end if
		
		repeat while ((item leftVal of theNumbers ≤ pivot) and (leftVal < rightVal))
			set leftVal to (leftVal + 1)
		end repeat
		
		if (leftVal ≠ rightVal) then
			
			set t to (item rightVal of theNumbers)
			set item rightVal of theNumbers to (item leftVal of theNumbers)
			set item leftVal of theNumbers to t
			set rightVal to (rightVal - 1)
		end if
	end repeat
	
	set item leftVal of theNumbers to pivot
	set pivot to leftVal
	set leftVal to l_hold
	set rightVal to r_hold
	if (leftVal < pivot) then
		q_sort(theNumbers, leftVal, pivot - 1)
	end if
	if (rightVal > pivot) then
		q_sort(theNumbers, pivot + 1, rightVal)
	end if
end q_sort

on quickSort(theNumbers, array_size)
	
	q_sort(theNumbers, 1, array_size) of me
	
	return theNumbers
end quickSort

quickSort({4, 6, 8, 3, 30, 12, 2, 23, 99, 100, 44, 76, 17, 1, 69, 98, 88, 4}, 18)

This sorting function has performance best-case of O(n log n), and worst case of O(n^2) which is basically what you already get with a bubble sort. You could swap in this function, or get a count of the number of events and if above say 10 switch to the quick sort function.

Model: iMac Core Duo 17"
Browser: Safari 419.3
Operating System: Mac OS X (10.4)