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

Haskell如何实现从列表中移除第N个奇数的功能

实现Haskell移除列表第N个奇数的函数

我们需要实现的removeOdd函数逻辑为:遍历列表时计数遇到的奇数,删除第N个命中的奇数,其余元素保持原有顺序不变,符合示例removeOdd 2 [2,4,3,6,5,8] == [2,4,3,6,8]。

基础递归实现(最易理解)

代码如下:

removeOdd :: Int -> [Int] -> [Int]
-- 空列表直接返回
removeOdd _ [] = []
removeOdd n (x:xs)
  -- 当前元素为偶数,直接保留,继续遍历剩余元素
  | even x = x : removeOdd n xs
  -- 当前元素为奇数
  | otherwise = if n == 1
                -- 刚好是要删除的第N个奇数,跳过当前元素,剩余元素直接返回
                then xs
                -- 不是目标奇数,保留当前元素,计数减1继续遍历
                else x : removeOdd (n - 1) xs

测试验证:运行removeOdd 2 [2,4,3,6,5,8],输出结果为[2,4,3,6,8],和预期完全一致。

边界处理增强版

如果需要对非法输入做校验,比如N为非正整数的场景,可以添加参数判断:

removeOdd :: Int -> [Int] -> [Int]
removeOdd n xs
  | n <= 0 = error "参数N必须为正整数"
  | otherwise = go n xs
  where
    go _ [] = []
    go cnt (x:rest)
      | even x = x : go cnt rest
      | otherwise = if cnt == 1 then rest else x : go (cnt - 1) rest

无显式递归的函数式写法

如果偏好使用高阶函数组合实现,可以用以下写法:

removeOdd :: Int -> [Int] -> [Int]
removeOdd n xs = map snd $ filter filterRule $ zip oddIndex xs
  where
    -- 为每个元素标注当前累计遇到的奇数个数
    oddIndex = tail $ scanl (\acc x -> if odd x then acc + 1 else acc) 0 xs
    -- 过滤规则:偶数全部保留,奇数只排除序号等于N的
    filterRule (idx, val) = even val || idx /= n

内容的提问来源于stack exchange,提问作者123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:54:03