1

以下のようにネストされたリストを想像してみてください。

["A","ABBA","ABABA"]

このリスト(この例では「A」)からシングルトン要素を削除し、そのシングルトン要素を含むリストをすべて削除する関数を作成したいと思います。

となることによって:

removeElems ["A","ABBA","CCC"] -> ["CCC"]

以下は、この問題を解決するための私の試みです。

badElements nested = concat $ filter (\c -> length c == 1) nested

removeElements nested = [c | c <- nested, u <- badElements nested, not $ any (==u) c]

これにより、次のように、複数のジェネレーターがネストされたリストを「循環」させるという奇妙な結果が生成されます。

["A","ABBA","C","BCCB"] --> ["A","A","ABBA","ABBA","C","C","BCCB","BCCB"]--> ["A","ABBA","C","BCCB"]

もう一つの例:

[[1],[1,2,3,4],[2],[5,6,7,8]] --> [5,6,7,8]
4

3 に答える 3

2

これがテストされていない試みです:

removeElements ls = filter (null . intersect singletons) ls
                    where singletons = mapMaybe singleElem ls
                          singleElem [x] = Just x
                          singleElem _ = Nothing
于 2011-02-07T16:11:28.040 に答える
2

リスト要素ごとに0個または1個の出力のみを生成する必要があるため、を繰り返すリスト内包は必要ありませんbadElements。代わりに、を繰り返す述語でフィルタリングする必要がありますbadElements

どんな述語?まあ、リストに悪い要素が含まれていなければ、リストは良いものです。つまり、そのすべての要素が悪くはありません。

removeElements nested = filter (all (`notElem` badElements nested)) nested
于 2011-02-07T16:34:02.383 に答える
1

別の試み:

badElements :: [[a]] -> [a]
badElements = concat . filter (\x -> 1 == length x)

removeBadElements :: (Eq a) => [[a]] -> [[a]]
removeBadElements xs = filter (\x -> not $ any ((flip elem) x) (badElements xs) ) xs

badElementsそのパラメータのすべてのシングルトン要素を含むリストを返します(あなたbadElementsがすることになっていることと同様です:

badElements [[1],[1,2,3,4],[2],[5,6,7,8]]
[1,2]

removeBadElements次に、の要素を含むすべての要素を削除しますbadElements

于 2011-02-07T16:29:40.100 に答える