Natural sorting: Difference between revisions
Content added Content deleted
No edit summary |
|||
Line 1,734: | Line 1,734: | ||
Implements requests 1-5. |
Implements requests 1-5. |
||
<lang haskell> |
<lang haskell> |
||
import Data.List |
|||
import Data.Char |
|||
import Data.String.Utils |
|||
import Data.List.Utils |
|||
import Data.Function (on) |
|||
printOutput = do |
|||
putStrLn "# Ignoring leading spaces \n" |
|||
printBlockOfMessages sample1Rule ignoringStartEndSpaces |
|||
putStrLn "\n # Ignoring multiple adjacent spaces (m.a.s) \n" |
|||
printBlockOfMessages sample2Rule ignoringMultipleAdjacentSpaces |
|||
putStrLn "\n # Equivalent whitespace characters \n" |
|||
printBlockOfMessages sample3Rule ignoringMultipleAdjacentSpaces |
|||
putStrLn "\n # Case Indepenent sorts \n" |
|||
printBlockOfMessages sample4Rule caseIndependent |
|||
putStrLn "\n # Numeric fields as numerics \n" |
|||
printBlockOfMessages sample5Rule numericFieldsAsNumbers |
|||
putStrLn "\n # Title sorts \n" |
|||
printBlockOfMessages sample6Rule removeLeadCommonWords |
|||
printMessage message content = do |
|||
putStrLn message |
|||
mapM_ print content |
|||
printBlockOfMessages list function = do |
|||
printMessage "Text strings:" list |
|||
printMessage "Normally sorted:" (sort list) |
|||
printMessage "Naturally sorted:" (sortListWith list function) |
|||
-- samples |
|||
sample1Rule = ["ignore leading spaces: 2-2", " ignore leading spaces: 2-1", " ignore leading spaces: 2+0", " ignore leading spaces: 2+1"] |
|||
sample2Rule = ["ignore m.a.s spaces: 2-2", "ignore m.a.s spaces: 2-1", "ignore m.a.s spaces: 2+0", "ignore m.a.s spaces: 2+1"] |
|||
sample3Rule = ["Equiv. spaces: 3-3", "Equiv.\rspaces: 3-2", "Equiv.\x0cspaces: 3-1", "Equiv.\x0bspaces: 3+0", "Equiv.\nspaces: 3+1", "Equiv.\tspaces: 3+2"] |
|||
sample4Rule = ["cASE INDEPENENT: 3-2", "caSE INDEPENENT: 3-1", "casE INDEPENENT: 3+0", "case INDEPENENT: 3+1"] |
|||
sample5Rule = ["foo100bar99baz0.txt", "foo100bar10baz0.txt", "foo1000bar99baz10.txt", "foo1000bar99baz9.txt"] |
|||
sample6Rule = ["The Wind in the Willows", "The 40th step more", "The 39 steps", "Wanda"] |
|||
-- function to execute all sorts |
|||
sortListWith l f = sort $ f l |
|||
-- 1. Ignore leading, trailing and multiple adjacent spaces |
|||
-- Ignoring leading spaces |
|||
-- receive a String and remove all spaces from the start and end of that String, a String is considered an List os Char |
|||
-- ex: " a string " = "a string" |
|||
ignoringStartEndSpaces :: [String] -> [String] |
|||
ignoringStartEndSpaces = map strip |
|||
-- Ignoring multiple adjacent spaces and Equivalent whitespace characters |
|||
ignoringMultipleAdjacentSpaces :: [String] -> [String] |
|||
ignoringMultipleAdjacentSpaces = map (unwords . words) |
|||
-- 2. Equivalent whitespace characters |
|||
-- 3. Case independent sort |
|||
-- lower case of an entire String |
|||
-- ex "SomeCAse" = "somecase" |
|||
caseIndependent :: [String] -> [String] |
|||
caseIndependent = map (map toLower) |
|||
-- 4. Numeric fields as numerics (deals with up to 20 digits) |
|||
numericFieldsAsNumbers :: [String] -> [[Int]] |
|||
numericFieldsAsNumbers = map findOnlyNumerics |
|||
findOnlyNumerics :: String -> [Int] |
|||
findOnlyNumerics s = convertDigitAsStringToInt $ makeListOfDigitsAsString $ extractDigitsAsString s |
|||
extractDigitsAsString :: String -> [String] |
|||
extractDigitsAsString s = map (filter isNumber) $ groupBy ((==) `on` isNumber ) s |
|||
makeListOfDigitsAsString :: [String] -> [String] |
|||
makeListOfDigitsAsString l = tail $ nub l |
|||
convertDigitAsStringToInt :: [String] -> [Int] |
|||
convertDigitAsStringToInt = map (joiner . map digitToInt) |
|||
-- join a list of numbers into a single number |
|||
-- ex [4,2] = 42 |
|||
joiner :: [Int] -> Int |
|||
joiner = read . concatMap show |
|||
-- 5. Title sort |
|||
removeLeadCommonWords l = map removeLeadCommonWord $ splitList l |
|||
splitList = map words |
|||
removeLeadCommonWord a = unwords $ if f a commonWords then tail a else a |
|||
where f l1 = elem (map toLower (head l1)) |
|||
commonWords = ["the","a","an","of"] |
|||
</lang> |
</lang> |
||
{{out}} |
|||
<pre style="height: 80ex; overflow: scroll"> |
|||
# Ignoring leading spaces |
|||
Text strings: |
|||
"ignore leading spaces: 2-2" |
|||
" ignore leading spaces: 2-1" |
|||
" ignore leading spaces: 2+0" |
|||
" ignore leading spaces: 2+1" |
|||
Normally sorted: |
|||
" ignore leading spaces: 2+1" |
|||
" ignore leading spaces: 2+0" |
|||
" ignore leading spaces: 2-1" |
|||
"ignore leading spaces: 2-2" |
|||
Naturally sorted: |
|||
"ignore leading spaces: 2+0" |
|||
"ignore leading spaces: 2+1" |
|||
"ignore leading spaces: 2-1" |
|||
"ignore leading spaces: 2-2" |
|||
# Ignoring multiple adjacent spaces (m.a.s) |
|||
Text strings: |
|||
"ignore m.a.s spaces: 2-2" |
|||
"ignore m.a.s spaces: 2-1" |
|||
"ignore m.a.s spaces: 2+0" |
|||
"ignore m.a.s spaces: 2+1" |
|||
Normally sorted: |
|||
"ignore m.a.s spaces: 2+1" |
|||
"ignore m.a.s spaces: 2+0" |
|||
"ignore m.a.s spaces: 2-1" |
|||
"ignore m.a.s spaces: 2-2" |
|||
Naturally sorted: |
|||
"ignore m.a.s spaces: 2+0" |
|||
"ignore m.a.s spaces: 2+1" |
|||
"ignore m.a.s spaces: 2-1" |
|||
"ignore m.a.s spaces: 2-2" |
|||
# Equivalent whitespace characters |
|||
Text strings: |
|||
"Equiv. spaces: 3-3" |
|||
"Equiv.\rspaces: 3-2" |
|||
"Equiv.\fspaces: 3-1" |
|||
"Equiv.\vspaces: 3+0" |
|||
"Equiv.\nspaces: 3+1" |
|||
"Equiv.\tspaces: 3+2" |
|||
Normally sorted: |
|||
"Equiv.\tspaces: 3+2" |
|||
"Equiv.\nspaces: 3+1" |
|||
"Equiv.\vspaces: 3+0" |
|||
"Equiv.\fspaces: 3-1" |
|||
"Equiv.\rspaces: 3-2" |
|||
"Equiv. spaces: 3-3" |
|||
Naturally sorted: |
|||
"Equiv. spaces: 3+0" |
|||
"Equiv. spaces: 3+1" |
|||
"Equiv. spaces: 3+2" |
|||
"Equiv. spaces: 3-1" |
|||
"Equiv. spaces: 3-2" |
|||
"Equiv. spaces: 3-3" |
|||
# Case Indepenent sorts |
|||
Text strings: |
|||
"cASE INDEPENENT: 3-2" |
|||
"caSE INDEPENENT: 3-1" |
|||
"casE INDEPENENT: 3+0" |
|||
"case INDEPENENT: 3+1" |
|||
Normally sorted: |
|||
"cASE INDEPENENT: 3-2" |
|||
"caSE INDEPENENT: 3-1" |
|||
"casE INDEPENENT: 3+0" |
|||
"case INDEPENENT: 3+1" |
|||
Naturally sorted: |
|||
"case indepenent: 3+0" |
|||
"case indepenent: 3+1" |
|||
"case indepenent: 3-1" |
|||
"case indepenent: 3-2" |
|||
# Numeric fields as numerics |
|||
Text strings: |
|||
"foo100bar99baz0.txt" |
|||
"foo100bar10baz0.txt" |
|||
"foo1000bar99baz10.txt" |
|||
"foo1000bar99baz9.txt" |
|||
Normally sorted: |
|||
"foo1000bar99baz10.txt" |
|||
"foo1000bar99baz9.txt" |
|||
"foo100bar10baz0.txt" |
|||
"foo100bar99baz0.txt" |
|||
Naturally sorted: |
|||
[100,10,0] |
|||
[100,99,0] |
|||
[1000,99,9] |
|||
[1000,99,10] |
|||
# Title sorts |
|||
Text strings: |
|||
"The Wind in the Willows" |
|||
"The 40th step more" |
|||
"The 39 steps" |
|||
"Wanda" |
|||
Normally sorted: |
|||
"The 39 steps" |
|||
"The 40th step more" |
|||
"The Wind in the Willows" |
|||
"Wanda" |
|||
Naturally sorted: |
|||
"39 steps" |
|||
"40th step more" |
|||
"Wanda" |
|||
"Wind in the Willows" |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |