[英]How do you filter a list of strings by a string in haskell?
I have a string containing letters I want to be sure are in the words in the list. 我有一个包含字母的字符串,我想确保它们在列表中的单词中。 Running it however results in it still leaving behind words that contain the undesired letters. 但是,运行它会导致它仍然留下包含不想要的字母的单词。
Here's my function: 这是我的功能:
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
What do I need to change to make this work? 要进行这项工作,我需要更改什么?
To make it clear, I want to filter away any words that contain letters not in "poultry outwits ants", meaning a word like "years" would be dropped because despite containing 'y'
, 'a'
, 'r'
, and 's'
which all satisfy the predicate, it also contains 'e'
which doesn't. 为了清楚起见,我想过滤掉所有不包含在“家禽智商”中的字母的单词,这意味着将删除“ years”之类的单词,因为尽管包含了'y'
, 'a'
, 'r'
和's'
都满足谓词的's'
,也包含不满足的'e'
。
A good way to filter a list of things (eg words) is to use the filter
function. 过滤事物列表(例如单词)的一种好方法是使用filter
功能。 What you need to provide is a predicate which tells whether a string should be included or not. 您需要提供一个谓词,该谓词告诉您是否应该包含字符串。 You commented that you want to include those strings which consists of letters in "poultry outwits ants"
, so that would be 您评论说要在"poultry outwits ants"
包含由字母组成的字符串,这样就可以
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord = all (`elem` "poultry outwits ants")
Now, in another comment you wrote that 现在,在另一条评论中,您写道
Some of the words I get have more copies of the same letter than there are in the original. 我得到的某些单词具有相同字母的副本多于原始副本。
So I suspect what you really want is to figure out which words can be formed out of the letters in "poultry outwits ants"
. 因此,我怀疑您真正想要的是找出可以用"poultry outwits ants"
中的字母组成的单词。
To do this, you could count how often each character appears in the given word (and in the mgic string poultry outwits ants
) and then verify that not only each letter in the word appears in the magic string but also that the letter doesn't appear more often than in the magic string. 为此,您可以计算每个字符在给定单词中(以及在mgic poultry outwits ants
)出现的频率,然后验证不仅单词中的每个字母都在魔术字符串中出现,而且该字母没有出现的频率比魔术弦中的频率高。
I'd start by defining a function which calculates 'character frequency table', ie it counts how often each character occurs in the given string: 我将从定义一个计算“字符频率表”的函数开始,即,它计算每个字符在给定字符串中出现的频率:
freq :: String -> [(Char, Int)]
freq = map (\s -> (head s, length s)) . group . sort
Furthermore, I'd define a function which tells whether one frequency table x
is a "subset" of another table y
, ie it verifies that each character in x
also appears in y
, but it doesn't occur more often: 此外,我将定义一个函数,该函数告诉一个频率表x
是否是另一个表y
的“子集”,即,它验证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
You can then use this to define acceptableWord
such that it only accepts words whose frequency table is a subset of the frequency table of the magic string, so we get: 然后,您可以使用它来定义acceptableWord
,以便它仅接受频率表是魔术字符串频率表的子集的单词,因此我们得到:
filterWords :: String -> [String]
filterWords str = filter acceptableWord (words str)
where
acceptableWord w = subset (freq w) (freq "poultry outwits ants")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.