I have two subroutines which 1) sorts a list (qsort) and 2) sorts a list of lists (sortListofLists). With these two subroutines the task didn’t seem that difficult no matter what amount of numbers you have in a row or the number of rows. The numbers don’t even have to be in order initially. The sorting takes care of all that. The final output is a list of lists sorted so that the numbers with the highest rate of occurrence are at the beginning.
The output of this script is {{3, 3}, {11, 2}, {10, 2}, {1, 2}, {9, 1}, {7, 1}, {5, 1}, {4, 1}, {2, 1}}
This means the number 3 occurs 3 times, the number 11 occurs 2 times, etc
set initialListOfLists to {{1, 2, 3, 7, 10}, {1, 3, 4, 10, 11}, {9, 3, 5, 11}}
-- first make the list of lists into one list so we can sort it
set combinedList to {}
repeat with aList in initialListOfLists
set combinedList to combinedList & aList
end repeat
-- sort the combined list
Qsort(combinedList, 1, -1)
-- iterate the sorted list and compile the number of times each value occurs
set countOfList to count of combinedList
set i to 1
set finalStats to {}
repeat until i is greater than countOfList
set thisValue to item i of combinedList
if (i + 1) is greater than countOfList then -- this happens if the last value is unique
set end of finalStats to {thisValue, 1}
exit repeat
else
repeat with j from (i + 1) to countOfList
if item j of combinedList is not equal to thisValue then exit repeat
if j is countOfList then -- this happens if the last value is not unique
set j to j + 1
exit repeat
end if
end repeat
end if
set end of finalStats to {thisValue, (j - i)}
set i to j
end repeat
-- sort the final stats and reverse it so the highest number of occurrences is shown first in the finalStats
set sortedFinalStats to sortListofLists(finalStats, 2)
set theReverse to reverse of sortedFinalStats
(*========== SUBROUTINES ============*)
on sortListofLists(array, sortItemNum) --> I modified a bublesort routine to make it work with a list of lists
repeat with i from length of array to 2 by -1 -- go backwards
repeat with j from 1 to i - 1 -- go forwards
if (item sortItemNum of (item j of array)) > (item sortItemNum of (item (j + 1) of array)) then
tell array to set {item j, item (j + 1)} to {item (j + 1), item j}
end if
end repeat
end repeat
return array
end sortListofLists
on Qsort(theList, l, r)
-- Qsort sorts a list
-- the authors of Qsort are Arthur Knapp and Nigel Garvey
-- the script can be found in item 2 of http://bbs.applescript.net/viewtopic.php?id=17340
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 (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 (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
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 (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
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 (v < u) then
set my p's item i to u
repeat with j from (i - 2) to l by -1
if (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
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 -- otherwise the handler will error
-- Translate negative indices
if (l < 0) then set l to listLen + l + 1
if (r < 0) then set r to listLen + r + 1
if (r = l) then
-- No point in sorting just one item
else
-- Transpose transposed indices
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
-- Skip the Quicksort if cutoff or less items
else
o's qsrt(l, r)
end if
o's isrt(l, r)
end if
end if
return -- the original name of your list is the returned value
end Qsort