2012-01-16 3 views
1

exputoolライブラリとHaskell言語を使用してPDFを作成することを目的としたプロジェクトを実行していますが、ファイルを注文する関数の作成に疑問があります。私の仕事は、今やPDFがソート機能を欠いているからです。私dat.hsファイルには、これらのファイル(音楽、ビデオ)sortOnのようなファイルを選択し、selectのようなフィルタを選択する方法

Files {files = [{filename = Video "-4th_dan trailer.mp4" size = "15 MB" ftype = "MP4" copyright = "-" height = "-", width = "720"} 
Video {filename = "TheLostInterview.mp4" size = "73 MB" ftype = "MP4" copyright = "-" height = "Bruce_Lee_-_The_Lost_Interview.avi" width = "240"} 
Audio {filename = "8bp017-08-nullsleep-humdrumz.mp3" size = "1984 kb", ftype = "MPG/3" copyright = "-", title = "humdrumz" artist = "nullsleep", year = "2001"} 
Audio {filename = "8bp017-04-nullsleep-fluffy_nougat.mp3" size = "1501 kb", ftype = "MPG/3" copyright = "-", title = "fluffy nougat," artist = "nullsleep" year = "2001"} 

が、私は今、このようなsortOn :: (Ord b) => (a -> b) -> [a] -> [a]select ((> 500). size) (dat files)などの機能を通じてサイズによって、これらのファイルを整理する必要が含まれているため例えば、年、アーティスト...

サイズとサイズでソートしたいので1つの問題は大きさとサイズが「15 MB」に設定されているためです。

答えて

2

私が正しく理解していれば、15 MB1984 kbより大きいとみなされます。

これを行う1つの方法は、sortOnではなくsortByを使用することです。 sortByは比較機能を使用し、それを使用してソートします。だから、ちょうど15 mbのような値をソートできる関数を書くことができます。

ただし、これを実行する最善の方法ではありません。代わりに、すべてのサイズを1単位(kb、おそらく)に正規化することをお勧めします。だから、15 MBをキロバイトに変換し、数字として保存してください。次に、サイズを印刷する必要がある場合は、数kbを要し、それを賞賛する関数を用意します。これにより、サイズを簡単にソートすることができます。これを行うには

方法はSizeタイプを作成することです:

newtype Size = Size Integer deriving (Eq, Ord) 

を次に、あなたはそれはかなりの印刷作業を取得するためにShowのインスタンスを作ることができます。

instance Show Size where 
    show (Size s) 
    | s < 1000 = show s ++ " kB" 
    | s < 1000000 = show (s `div` 1000) ++ " mB" 
    | otherwise = show (s `div` 1000000) ++ " gB" 

取得するにはサイズが入力文字列の場合は、Readのインスタンスにすることができます。

instance Read Size where 
    readsPrec _ str = do (size, rest) <- reads str 
         (unit, rest') <- lex rest 
         let multiplier = fromMaybe 1 $ lookup unit unitSizes 
         return (Size $ multiplier * size, rest') 
    where unitSizes = [("mB", 1000), ("gB", 1000000)] 

あなただけunitSizesに多くのペアを追加することにより、ユニット名(例えば「ヘクトパスカル」と「MB」)の変異体を含むことができます。リストにない単位の略語は無視されます。

編集:Daniel Wagnerの提案を使用して、コードをきれいにしました。

その他の注意事項:

あなたがSizeを定義し、それをそれらの型クラスのすべてのインスタンスを作ったら、あなたはそれを通常の並べ替えを使用することができます。あなたは"10 mB"のようなものにreadを使用してサイズを得ることができます。元のデータ型にderiving (show)を使用する場合は、文字列をSizeに置き換えても正しく動作するはずです。

+0

特定のReadインスタンスが適切なコードであるかどうかわかりません。もし誰かがそれを編集し改善することができたら、私は感謝します。 –

+0

私の質問 に応答してくれたことを前もってありがとう。すべてのケースのケースを正しくするために、MBのペアkbの型サイズを変更する必要があります。これらの機能はあなたが話していることをしていますか? – user1151066

+0

もう1つ、この関数はSortBy sortOnと非常によく似ていますか? が序曲で定義されているか、最初に行う必要がありますか? ありがとうございました – user1151066

関連する問題