首页 > 解决方案 > 是否有一个直接的解决方案来接收元素 *prior* 击中 dropWhile 谓词?

问题描述

给定一个条件,我想搜索一个元素列表并返回第一个达到条件的元素和前一个元素。

在 C/C++ 中,这很容易:

int i = 0;
for(;;i++) if (arr[i] == 0) break;

在我们得到满足条件的索引后,获取前一个元素就很容易了,通过“ arr[i-1]

在哈斯克尔:

但我看不到以简单的方式获得两者的方法。我可以枚举列表并使用索引,但这似乎很乱。有没有正确的方法来做到这一点,或者解决这个问题的方法?

标签: haskellfunctional-programming

解决方案


我会用它的尾部压缩列表,这样你就有可用的元素对。然后你可以find在对列表中使用:

f :: [Int] -> Maybe (Int, Int)
f xs = find ((>3) . snd) (zip xs (tail xs))

> f [1..10]
Just (3,4)

如果第一个元素与谓词匹配,这将返回 Nothing(或者第二个匹配,如果有的话),所以如果你想要不同的东西,你可能需要特殊情况。

正如 Robin Zigmond 所说break,也可以工作:

g :: [Int] -> (Int, Int)
g xs = case break (>3) xs of (_, []) -> error "not found"
                             ([], _) -> error "first element"
                             (ys, z:_) -> (last ys, z)

(或者也有这个返回 a Maybe,这取决于你需要什么。)

但我认为,这会将整个前缀保留ys在内存中,直到找到匹配项,而f可以开始垃圾收集它已经移动过去的元素。对于小列表,这并不重要。


推荐阅读