[英]The lower value from a tuple of words and values in haskell
我正在尝试编写一个函数,该函数选择具有较低值的元组,并且元组由一个单词和一个值组成。
例如,对于这样的元组列表:[(“ CHURCH”,262),(“ PENCIL”,311),(“ FLOUR”,175),(“ FOREST”,405),(“ CLASS”, 105)],该函数将返回(“ CLASS”,105)
有人可以帮我吗? :)
非常感谢!
您正在Data.List
模块中寻找函数minimumBy
。 它的类型是
minimumBy :: (a -> a -> Ordering) -> [a] -> a
在您的情况下,从具有以下类型的Data.Ord
模块中导入comparing
也很有用
comparing :: Ord a => (b -> a) -> b -> b -> Ordering
这使您可以为它提供“访问器”功能来创建订单。 所以在这种情况下,您可以
minimumSnd :: [(String, Int)] -> (String, Int)
minimumSnd = minimumBy (comparing ???)
我让你填写???
,这时应该很容易。 您的访问器函数传递给comparing
是什么类型?
如果您想为此编写自定义函数,则建议使用fold
模式。 我们还可以利用这个机会通过返回Maybe
类型来使其更安全,而不是要求它成为(String, Int)
的列表,从而使其更通用:
minimumSnd :: (Ord b) => [(a, b)] -> Maybe (a, b)
minimumSnd = go Nothing
where
-- If the list is empty, just return our accumulator
go acc [] = acc
-- If we haven't found a minimum yet, grab the first element and use that
go Nothing (x:xs) = go (Just x) xs
-- If we have a minimum already, compare it to the next element
go (Just currentMin) (x:xs)
-- If it's <= our current min, use it
| snd x <= snd currentMin = go (Just x) xs
-- otherwise keep our current min and check the rest of the list
| otherwise = go (Just currentMin) xs
尝试这个:
foldl1 (\acc x -> if snd x < snd acc then x else acc) <your list>
您可以通过将列表的当前元素与下一个元素进行比较来折叠列表。 如果下一个元素的第二个值小于当前元素的值,则它是累加器的新值。 否则,累加器保持不变。 重复此过程,直到遍历了整个列表。
我是Haskell的初学者,但我还是想找到一个可行的解决方案,并提出了:
minTup' :: [(String, Int)] -> Maybe (String, Int) -> (String, Int)
minTup' [] (Just x)= x
minTup' (x:xs) Nothing = minTup' xs (Just x)
minTup' ((s,n):xs) (Just (s',n'))
| n < n' = minTup' xs (Just (s,n))
| otherwise = minTup' xs (Just (s',n'))
minTup :: [(String, Int)] -> (String, Int)
minTup [] = error "Need a list of (String,Int)"
minTup x = minTup' x Nothing
main = do
print $ minTup [("CHURCH",262),("PENCIL",311),("FLOUR",175),("FOREST",405),("CLASS",105)]
print $ minTup [("CHURCH",262)]
print $ minTup []
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.