简体   繁体   English

haskell中元组列表中4的唯一组合

[英]Unique combinations of 4 from a list of tuples in haskell

I have a list of tuples that repeats and is in no particular order. 我有一个重复的元组列表,并且没有特定的顺序。 heres an example 这是一个例子

let list = [(0,0), (0,1), (1,0), (1,1), (1,2)]

I want to filter this list and get every unique combination of 4 tuples from the list 我想过滤此列表,并从列表中获取4个元组的每个唯一组合

I found example code to get a unique list where order doesn't matter and i'm not sure how to adapt it to get a unique set of 4. 我找到了示例代码来获取顺序无关紧要的唯一列表,而且我不确定如何修改它以获取唯一的4个集合。

with the above list the output there would be 2 unique sets of 4. 使用上面的列表,输出将有2个唯一的4组。

     [(0, 0), (0, 1), (1, 0), (1, 1)] 
     [(0, 1), (1, 0), (1, 1), (1, 2)] 
     [(0, 0), (0, 1), (1, 0), (1, 2)]  
     [(0, 0), (0, 1), (1, 1), (1, 2)]  
     [(0, 0), (1, 0), (1, 1), (1, 2)]

Something like this in the list monad lets you pick out all combinations easily. monad列表中的类似内容使您可以轻松挑选所有组合。 The Set.fromList gives us (==) defined on Set.Set s which ignore order. Set.fromList给我们(==)Set.Set定义的,忽略顺序。

import           Data.List ((\\), nub)
import qualified Data.Set as Set

someFours xs = nub $ do
  let xs' = nub xs
  choice1 <- xs'
  choice2 <- xs' \\ [choice1]
  choice3 <- xs' \\ [choice1, choice2]
  choice4 <- xs' \\ [choice1, choice2, choice3]
  return $ Set.fromList [choice1, choice2, choice3, choice4]

One solution is to use 一种解决方案是使用

let sane = nub list in filter (\x -> length x == 4) $ filterM (const [True, False]) sane

The sane = nub list is needed to remove duplicates in the original list. 需要使用sane = nub list才能删除原始列表中的重复项。 The filterM ... part get's you all the sets in the powerset of sane and from here we only select those with length 4 . filterM ...部分让您获得sane的幂集中的所有集合,从这里我们仅选择长度为4那些。

The above is not efficient due to the fact that we generate all elements of the powerset first. 由于我们首先生成powerset的所有元素,因此上述方法效率不高。 Use J. Abrahamson's answer if performance is needed. 如果需要性能,请使用J. Abrahamson的答案

A somewhat efficient and compact solution might be this (assuming I've correctly understood your question): 可能是一个有效而紧凑的解决方案(假设我已经正确理解了您的问题):

import Data.List (nub)

kSubsets :: (Eq a) => Int -> [a] -> [[a]]
kSubsets k = go k . nub
  where
    go 0 _      = [[]]
    go n []     = []
    go n (x:xs) = map (x:) (go (n-1) xs) ++ go n xs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM