2017-09-04 10 views
0

["A1","A2","A3"]["A3","A2","A1"]のような多くの重複要素を含む[["A1","A1","A1"] .. ["G3","G3","G3"]]という形式のリストがあります。フィルタ[Haskell]の重複要素

このような重複要素を除外するにはどうすればよいですか?

平等のための上記2つの要素をチェックすると、それは偽

*Main> ["A1","A2","A3"] == ["A3","A2","A1"] 
False 
+0

重複の定義は何ですか。同じ要素を別の順序で使用していますか? '[" A1 "、" A2 "のリストではなく[マルチセット](https://hackage.haskell.org/package/multiset-0.3.3/docs/Data-MultiSet.html) "、" A3 "]'。 – rampion

答えて

3

nubBy :: (a -> a -> Bool) -> [a] -> [a]を任意の等価試験を介してリストから重複を削除し、関連する機能であることを示しています。

、あなたが探している機能のバージョンは次のとおりです。もちろん

import Data.List (sort, nubBy) 

removeDuplicates' :: Ord a => [[a]] -> [[a]] 
removeDuplicates' = nubBy (\l1 l2 = sort l1 == sort l2) 

、これはaが(ようであるOrdだけではなく、Eqだけでなく、sortを使用して、あることを必要としません以下に述べる)高価な機能。それは確かに理想的ではありません。しかし、私はこれらのリストの平等テストをどのようにしたいのかは分かりませんので、詳細を残しておきます。

1

@AJFarmar's answerが問題を解決します。しかし、それはより効率的に行うことができます:sortは高価な機能です。このような関数呼び出しを保存したい。

我々は使用することができます。

import Data.List(nubBy, sort) 
import Data.Function(on) 

removeDuplicates' :: Ord a => [[a]] -> [[a]] 
removeDuplicates' = map snd . nubBy ((==) `on` fst) . map ((,) =<< sort) 

は、私たちはここにある最初のmap ((,) =<< sort)を構築します。つまり、元のリストのすべての要素xに対して、タプル(sort x,x)を作成します。ここでは、並べ替える2つのタプルの最初の要素に対してnubByを実行します。ソート後、map sndを実行します。ここでは、すべてのタプルに対して(sort x,x)が2番目の項目を返します。

我々はnubOn機能を構築することにより、これを一般化することができます。その場合は

import Data.List(nubBy) 
import Data.Function(on) 

nubOn :: Eq b => (a -> b) -> [a] -> [a] 
nubOn f = map snd . nubBy ((==) `on` fst) . map ((,) =<< f) 

removeDuplicates'nubOn sortです。

0

ソートする必要はありません。あなたは、すべてのアイテムが同じものであるかどうかを確認する必要があります。

\xs ys -> length xs == (length . filter (== True) $ (==) <$> xs <*> ys) 

はあなただけ(==) <$> ["A1","A2","A3"] <*> ["A3","A2","A1"]が実際にのは、さらにそれを取るとData.Setが、それはかなりダンディ取得インポートしましょう@rampionの正当なコメントを1として[False,False,True,False,True,False,True,False,False]

を返すことを知っておく必要があります。

import Data.Set as S 

equity :: Ord a => [a] -> [a] -> Bool 
equity = (. S.fromList) . (==) . S.fromList 

*Main> equity ["A1","A2","A3"] ["A3","A2","A1"] 
True 
+0

両方のリストの長さが 'n'の場合、ソートして比較すると' O(n log n) 'になりますが、このチェックは厳密にはより高価な' O(n^2) 'です。 – rampion