如何通过 haskell 中的字符串过滤字符串列表?
How do you filter a list of strings by a string in haskell?
我有一个包含字母的字符串,我想确定它在列表中的单词中。 运行 然而,它仍然会留下包含不需要的字母的单词。
这是我的函数:
import Data.List
filterWords :: String -> [String]
filterWords str =
let strs = words str
letters = concat . words . nub $ "poultry outwits ants"
predicate = dropWhile (`elem` letters) ['a' .. 'z']
in dropWhile (any (`elem` predicate)) strs
我需要更改什么才能使这项工作正常进行?
为了清楚起见,我想过滤掉任何包含不在 "poultry outwits ants" 中的字母的单词,这意味着像 "years" 这样的单词将被删除,因为尽管包含 'y'
,[ =13=, 'r'
, 和 's'
都满足谓词,它还包含不满足谓词的 'e'
.
过滤事物列表(例如单词)的一个好方法是使用 filter
函数。您需要提供的是一个谓词,它告诉您是否应该包含一个字符串。你评论说你想包括那些由 "poultry outwits ants"
中的字母组成的字符串,所以那将是
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord = all (`elem` "poultry outwits ants")
现在,您在另一条评论中写道
Some of the words I get have more copies of the same letter than there are in the original.
所以我怀疑你真正想要的是找出哪些单词可以由 "poultry outwits ants"
.
中的字母组成
为此,您可以计算每个字符在给定单词(以及 mgic 字符串 poultry outwits ants
)中出现的频率,然后验证不仅单词中的每个字母都出现在魔术字符串中,而且此外,该字母的出现频率并不比魔术字符串中的频率高。
我首先定义一个计算 'character frequency table' 的函数,即计算每个字符在给定字符串中出现的频率:
freq :: String -> [(Char, Int)]
freq = map (\s -> (head s, length s)) . group . sort
此外,我将定义一个函数来判断一个频率 table x
是否是另一个 table y
的 "subset",即它验证 x
中的每个字符也出现在 y
中,但出现频率不高:
subset :: [(Char, Int)] -> [(Char, Int)] -> Bool
subset x y = all f x
where
f (ch, occ) = case lookup ch y of
Just occ' -> occ <= occ'
Nothing -> False
然后您可以使用它来定义 acceptableWord
,这样它只接受频率 table 是魔术字符串频率 table 的子集的单词,所以我们得到:
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord w = subset (freq w) (freq "poultry outwits ants")
我有一个包含字母的字符串,我想确定它在列表中的单词中。 运行 然而,它仍然会留下包含不需要的字母的单词。
这是我的函数:
import Data.List
filterWords :: String -> [String]
filterWords str =
let strs = words str
letters = concat . words . nub $ "poultry outwits ants"
predicate = dropWhile (`elem` letters) ['a' .. 'z']
in dropWhile (any (`elem` predicate)) strs
我需要更改什么才能使这项工作正常进行?
为了清楚起见,我想过滤掉任何包含不在 "poultry outwits ants" 中的字母的单词,这意味着像 "years" 这样的单词将被删除,因为尽管包含 'y'
,[ =13=, 'r'
, 和 's'
都满足谓词,它还包含不满足谓词的 'e'
.
过滤事物列表(例如单词)的一个好方法是使用 filter
函数。您需要提供的是一个谓词,它告诉您是否应该包含一个字符串。你评论说你想包括那些由 "poultry outwits ants"
中的字母组成的字符串,所以那将是
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord = all (`elem` "poultry outwits ants")
现在,您在另一条评论中写道
Some of the words I get have more copies of the same letter than there are in the original.
所以我怀疑你真正想要的是找出哪些单词可以由 "poultry outwits ants"
.
为此,您可以计算每个字符在给定单词(以及 mgic 字符串 poultry outwits ants
)中出现的频率,然后验证不仅单词中的每个字母都出现在魔术字符串中,而且此外,该字母的出现频率并不比魔术字符串中的频率高。
我首先定义一个计算 'character frequency table' 的函数,即计算每个字符在给定字符串中出现的频率:
freq :: String -> [(Char, Int)]
freq = map (\s -> (head s, length s)) . group . sort
此外,我将定义一个函数来判断一个频率 table x
是否是另一个 table y
的 "subset",即它验证 x
中的每个字符也出现在 y
中,但出现频率不高:
subset :: [(Char, Int)] -> [(Char, Int)] -> Bool
subset x y = all f x
where
f (ch, occ) = case lookup ch y of
Just occ' -> occ <= occ'
Nothing -> False
然后您可以使用它来定义 acceptableWord
,这样它只接受频率 table 是魔术字符串频率 table 的子集的单词,所以我们得到:
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord w = subset (freq w) (freq "poultry outwits ants")