Haskell入门问题:实现1起始索引的列表元素获取函数ele
Haskell 1起始索引列表取元素函数实现
你当前写的numberList有明显的长度限制问题:zip x [1..10]只会给前10个元素配对序号,列表长度超过10时后续元素会直接丢失,把[1..10]换成无界的正整数流[1..]即可修复这个问题。
下面提供两种可运行的实现方案:
方案1:沿用你编写的numberList辅助函数实现
先修正辅助函数的长度限制问题:
numberList :: [a] -> [(a, Int)] numberList x = zip x [1..]
主函数通过遍历带序号的元组列表匹配目标索引,匹配到空列表时抛出和内置!!一致的越界错误:
ele :: Int -> [a] -> a ele n xs = lookupWithIdx n (numberList xs) where lookupWithIdx _ [] = error "ele: index out of range" lookupWithIdx target ((val, idx):tail) | idx == target = val | otherwise = lookupWithIdx target tail
方案2:无需辅助函数的直接递归实现(更推荐)
构造元组列表会产生额外的内存开销,直接通过模式匹配递归实现性能更好,逻辑也更直观:
ele :: Int -> [a] -> a ele _ [] = error "ele: index out of range" ele 1 (x:_) = x ele n (_:xs) | n < 1 = error "ele: index must be a positive integer" | otherwise = ele (n - 1) xs
逻辑说明
- 传入空列表时,直接抛出索引越界错误
- 当目标索引为1时,当前列表的首元素就是目标值,直接返回
- 目标索引大于1时,跳过当前首元素,将索引减1后递归查找剩余列表
- 增加了小于1的非法索引判断,避免传入0或者负数时出现无意义的递归
用你给出的测试用例验证结果如下:
ele 1 [1,2,3]返回1ele 2 [3,4,5,6]返回4
完全符合预期行为。
内容的提问来源于stack exchange,提问作者el Kusn
相关产品推荐
相关产品推荐

