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

Haskell中如何生成无重复二元子列表并添加筛选条件?

在Haskell中生成无序二元子列表并支持筛选

嘿,这个需求很实用,咱们一步步来实现它!核心要解决两个问题:一是生成不重复的无序二元子列表(比如[1,2]和[2,1]只保留一个),二是扩展支持自定义筛选条件。

第一步:生成基础的无序二元子列表

要避免逆序重复,关键逻辑是:只取列表中前面元素与后续元素的组合——也就是每个元素只和它之后的元素配对,从根源上杜绝[2,1]这种重复项。

这里有两种直观的实现方式:

方式1:递归实现(逻辑易懂)

这种写法适合新手理解递归的思路:

uniquePairs :: [a] -> [[a]]
uniquePairs [] = []  -- 空列表没有任何子列表
uniquePairs (x:xs) = 
  map (\y -> [x, y]) xs  -- 把当前元素x和后面所有元素逐一配对
  ++ uniquePairs xs      -- 递归处理剩下的子列表

测试效果:

> uniquePairs [1,2,3]
[[1,2],[1,3],[2,3]]

完全符合你的预期!

方式2:用tails的列表推导式(简洁优雅)

如果你偏爱更紧凑的代码,可以用Data.List模块里的tails函数(需要先导入import Data.List):

import Data.List (tails)

uniquePairs :: [a] -> [[a]]
uniquePairs xs = [[x, y] | (x:ys) <- tails xs, y <- ys]

tails [1,2,3]会生成[[1,2,3],[2,3],[3],[]],我们遍历每个非空的(x:ys),再从ys里取元素y,自然保证了x在y的前面,不会出现逆序重复对。

第二步:添加自定义筛选条件

接下来扩展函数,让它支持传入任意筛选规则。只需要在生成配对的过程中加入条件判断即可:

带筛选功能的版本

还是用列表推导式,保持代码简洁性:

import Data.List (tails)

filteredUniquePairs :: (a -> a -> Bool) -> [a] -> [[a]]
filteredUniquePairs cond xs = 
  [[x, y] | (x:ys) <- tails xs, y <- ys, cond x y]

这里的cond是一个二元函数,用来判断配对(x,y)是否符合你的筛选要求。

测试筛选场景

比如你需要“子列表元素之和小于4”,就传入对应的条件函数:

> filteredUniquePairs (\x y -> x + y < 4) [1,2,3]
[[1,2]]

完美得到你想要的结果!

如果有其他筛选需求,比如要求两个元素都是偶数,就可以传(\x y -> even x && even y),灵活性拉满。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:55:47