You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何一次性获取列表中满足断言条件的元素及其索引?

同时获取满足断言的元素及其索引的Haskell实现

好问题!在Haskell的标准库中,确实没有直接返回满足断言的元素及其对应索引的现成函数,但我们可以通过两种简单的方式实现这个需求:要么利用现有标准库函数组合,要么手动写递归实现。

方法一:用标准库函数组合(简洁高效)

我们可以先通过zip [0..]把列表的每个元素和它的索引配对,之后再用filter筛选出满足条件的配对。这样只需要一次遍历列表,比你原来先找索引再取元素的两次遍历更高效。

示例代码:

-- 给列表元素配上从0开始的索引
addIndices :: [a] -> [(Int, a)]
addIndices = zip [0..]

-- 过滤出满足断言的(索引,元素)对
filterWithIndices :: (a -> Bool) -> [a] -> [(Int, a)]
filterWithIndices pred = filter (pred . snd) . addIndices

用你给出的列表测试:

list :: [Int]
list = [3,2,4,1,9]

-- 调用函数
result = filterWithIndices (>2) list
-- 输出结果:[(0,3), (2,4), (4,9)]

方法二:手动递归实现(直观易懂)

如果你想更清楚地理解底层逻辑,可以写一个递归函数,从索引0开始遍历列表,遇到满足条件的元素就将其索引和元素加入结果列表:

filterWithIndices' :: (a -> Bool) -> [a] -> [(Int, a)]
filterWithIndices' pred = go 0
  where
    go _ [] = []  -- 空列表直接返回空
    go idx (x:xs)
      | pred x    = (idx, x) : go (idx + 1) xs  -- 满足条件,保留并继续遍历
      | otherwise = go (idx + 1) xs             -- 不满足,跳过当前元素

同样用你的列表测试,得到的结果和方法一完全一致。

对比你原来的实现

你原来的方法需要两次遍历列表:一次用findIndices找索引,一次通过列表推导式取元素。而上面的两种方法都只需要一次遍历,在处理大型列表时性能会更优,同时代码也更简洁直观。

内容的提问来源于stack exchange,提问作者Stéphane Laurent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:38:37