haskell - 是否有一个直接的解决方案来接收元素 *prior* 击中 dropWhile 谓词?
问题描述
给定一个条件,我想搜索一个元素列表并返回第一个达到条件的元素和前一个元素。
在 C/C++ 中,这很容易:
int i = 0;
for(;;i++) if (arr[i] == 0) break;
在我们得到满足条件的索引后,获取前一个元素就很容易了,通过“ arr[i-1]
”
在哈斯克尔:
dropWhile (/=0) list
给了我们我想要的最后一个元素takeWhile (/=0) list
给了我们我想要的第一个元素
但我看不到以简单的方式获得两者的方法。我可以枚举列表并使用索引,但这似乎很乱。有没有正确的方法来做到这一点,或者解决这个问题的方法?
解决方案
我会用它的尾部压缩列表,这样你就有可用的元素对。然后你可以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
可以开始垃圾收集它已经移动过去的元素。对于小列表,这并不重要。
推荐阅读
- ios - iOS:Almofire PUT 和 DELETE 调用不适用于 Swift 中的参数
- python-3.x - 如何测试读取 s3Bucket 中的文件?
- excel - 问题计数值,不返回任何东西
- amazon-cloudformation - Unexpected close tag in aws cdk deploy
- c++ - 成员函数有没有办法知道对象是右值还是左值?
- python - Python-pptx:改变堆积条形图的颜色
- python - TypeError: ufunc 循环不支持 csr_matrix 类型的参数 0,它没有可调用的 exp 方法
- palantir-foundry - 如何从铸造融合表中删除重复的行
- arrays - 将列表框的选择存储在数组 VBA 中
- installshield - InstallShield 2011:缺少预定义变量