2012-04-07 7 views
2

リスト内の各個別の値がそのリストに何回現れるかをカウントする関数(頻度)があります。例えば、sort Haskellを使用してペアのリストをソート

frequency "ababca" 

を返す必要があります:

[(3, 'a'), (2, 'b'), (1, 'c')]. 

をこれが正常に動作しますが、今、私はこの機能を使用して、リストのリスト内の最初の要素を使用してリストをソートする必要があります。所望の出力の

results :: [Party ] -> [(Int, Party)] 
results xs = ??? frequency (sort xs) ??? 

例:上記は動作しません

[(1, "Green"), (2, "Red"), (3, "Blue")] 

、私は私が何ができるか見当がつかない。定期的に 'ソート'

を使用して

は事前にありがとうございます。 onのドキュメントへ

+1

Haskellがカンマを使用するセミコロンを使用していることに注意してください。 – dave4420

答えて

8
import Data.Function (on) 
import Data.List (sortBy) 

results xs = sortBy (compare `on` fst) (frequency xs) 

-- or, if you prefer 
results xs = sort (frequency xs) 

リンク、sortBycomparefstsortBy (compare `on` fst)が明示的にのみ各ペアの最初の要素を見ながら

違いは、ペアの第二の要素とタイブレークを破る各ペアの最初の要素の昇順にソートsort、ということです。

+0

上記と同じように通常の「ソート」を使用するにはどうすればよいですか? – ErHunt

+1

@Badr私の編集を参照してください。 – dave4420

+1

'(compare \ on fst)'の代わりに '(fstを比較する)'を使うことができます。 – pat

2

を使用でき、sortBy(何らかの理由で!)を使用できない場合は、アイテムのタイプがOrdであることを確認する必要があります。すべてのタプル(サイズ15まで)はOrdのインスタンスを持ちますが、すべてのタプルの位置もOrdのインスタンスであることが条件です。

IntString両方がOrdのインスタンスを持っているので、あなたは、必要があるソートファイン(逆にいえ)(1, "Green"), (2, "Red"), (3, "Blue")]の与える例。

しかし、コードスニペットでは、Partyというタイプも実際には何も言わずに記述されています。 Stringのようなエイリアスだけではない場合は、組み込みOrdインスタンスのタプルを満たすために、Ordインスタンスを定義する必要があります。

あなたがタイプ

data Party = P1 | P2 | P3 | P4 -- e.g. 
    deriving (Eq,Ord) 

またはそれを自分で宣言を宣言するときderivingを使用して、Haskellはあなたのためのインスタンスを作成することができます:

instance Ord Party where 
    -- you don't care about the ordering of the party values 
    compare a b = EQ 

しかし、dave4420が言うように、それだけにずっとましですsortByを使用してください。特定の理由がない限り(つまり、制限付きのクラス割り当てです)、そうしない限り、私はそれを行います。

関連する問題