如何在Haskell中实现同一列表的嵌套迭代(内层从当前位置开始)
Haskell 实现从当前位置开始的嵌套列表迭代
先明确需求:生成列表中所有前元素在前、后元素在后的元素对(即内层迭代从外层当前元素的下一个位置开始),先看你提到的参考实现:
参考示例
C语言for循环实现
int arr[] = {1,2,3,4}; int n = sizeof(arr)/sizeof(arr[0]); for (int i = 0; i < n; i++) { for (int j = i+1; j < n; j++) { printf("(%d, %d)\n", arr[i], arr[j]); } }
Python列表推导式实现
lst = [1,2,3,4] pairs = [(x,y) for i,x in enumerate(lst) for y in lst[i+1:]]
Haskell函数式实现方案
以下两种方式均为纯函数式写法,无需依赖索引:
方案1:利用tails函数
tails会返回列表的所有后缀(例如tails [1,2,3,4]结果为[[1,2,3,4], [2,3,4], [3,4], [4], []]),结合concatMap即可实现需求:
import Data.List (tails) pairs :: [a] -> [(a, a)] pairs = concatMap (\(x:xs) -> map (x,) xs) . init . tails
init . tails去掉最后一个空后缀,避免无效处理- 对每个非空后缀
x:xs,用map (x,) xs生成当前外层元素x与后续所有元素的配对 concatMap将所有配对列表拼接为最终结果
方案2:递归实现
如果不想依赖库函数,直接用递归更直观:处理当前元素时,先生成它与后续所有元素的配对,再递归处理剩余列表:
pairsRec :: [a] -> [(a, a)] pairsRec [] = [] pairsRec (x:xs) = map (x,) xs ++ pairsRec xs
两种方案测试结果一致,例如pairs [1,2,3,4]会返回[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)],完全符合需求。
内容的提问来源于stack exchange,提问作者João Haas
相关产品推荐
相关产品推荐

