Haskell中按指定索引提取嵌套列表子元素的实现
在Haskell中按指定索引提取子列表元素的实现方法
这个需求在Haskell里实现起来非常直观,我们可以利用高阶函数和列表索引操作来完成批量提取。
核心函数实现
我们可以定义一个通用函数extractIndices,它接收两个参数:一个表示要提取的索引列表,以及目标嵌套列表,最终返回提取后的新嵌套列表。
基础版本
extractIndices :: [Int] -> [[a]] -> [[a]] extractIndices indices = map (\sublist -> map (sublist !!) indices)
更简洁的函数组合版本
如果你喜欢函数式风格的简洁写法,也可以用函数组合来改写:
extractIndices :: [Int] -> [[a]] -> [[a]] extractIndices indices = map (flip map indices . (!!))
代码解释
(!!)是Haskell内置的列表索引操作符,sublist !! i表示取子列表sublist中第i个元素(索引从0开始,正好匹配题目中的需求)。- 内层的
map (sublist !!) indices会遍历索引列表,从当前子列表中依次提取对应索引的元素,组成新的子列表。 - 外层的
map会把这个提取操作应用到嵌套列表的每一个子列表上,最终得到我们想要的结果。
测试示例
我们用题目中的示例来验证:
-- 定义题目中的嵌套列表 ghci> let nestedList = [[0,4,1,4],[1,12,1,4],[2,8,1,4],[3,54,2,4],[4,1,2,2]] -- 测试第一个索引列表 [2,3] ghci> extractIndices [2,3] nestedList [[1,4],[1,4],[1,4],[2,4],[2,2]] -- 测试第二个索引列表 [0,2,3] ghci> extractIndices [0,2,3] nestedList [[0,1,4],[1,1,4],[2,1,4],[3,2,4],[4,2,2]]
结果完全符合题目中的期望输出。
注意事项
- 要确保目标嵌套列表中的每个子列表长度都大于索引列表中的最大索引,否则
(!!)会抛出IndexOutOfBounds异常。 - 如果需要处理索引越界的情况,可以引入
Maybe类型来安全处理,比如使用Control.Lens库中的ix函数:
这个版本会返回包含import Control.Lens (ix) safeExtractIndices :: [Int] -> [[a]] -> [[Maybe a]] safeExtractIndices indices = map (\sublist -> map (\i -> sublist ^? ix i) indices)Maybe值的列表,越界的索引会返回Nothing,合法索引返回Just 元素。
内容的提问来源于stack exchange,提问作者Andre Proenza
相关产品推荐
相关产品推荐

