list - 从 Haskell 的列表中删除共轭元组

标签 list haskell tuples

我有一个元组列表。每个元组也是一个元组。对于每个外部元组,我都有一个共轭元组。我的意思是,如果列表中有 (a,b),那么我也有 (b,a)。我想要的是从列表中删除共轭元组。

这里是我的列表的具体示例:

[((1,2,1,0),(5,2,1,0)),((2,4,4,0),(2,5,4,0)) ,((2,5,4,0),(2,4,4,0)),((3,1,1,0),(3,3,2,0)),((3,3 ,2,0),(3,1,1,0)),((5,1,7,0),(8,1,7,0)),((5,2,1,0), (1,2,1,0)),((5,5,8,0),(8,5,8,0)),((5,6,6,0),(8,6,8 ,0)),((5,9,9,0),(8,9,9,0)),((6,3,5,0),(6,8,9,0)),( (6,8,9,0),(6,3,5,0)),((7,7,6,0),(9,7,6,0)),((8,1,7 ,0),(5,1,7,0)),((8,5,8,0),(5,5,8,0)),((8,6,8,0),(5 ,6,6,0)),((8,9,9,0),(5,9,9,0)),((9,7,6,0),(7,7,6,0 ))]

去除共轭元组后的结果应该是:

[((1,2,1,0),(5,2,1,0)),((2,4,4,0),(2,5,4,0)) ,((3,1,1,0),(3,3,2,0)),((5,1,7,0),(8,1,7,0)),((5,5 ,8,0),(8,5,8,0)),((5,6,6,0),(8,6,8,0)),((5,9,9,0), (8,9,9,0)),((6,3,5,0),(6,8,9,0)),((7,7,6,0),(9,7,6 ,0)),]

我试了几个小时都没有成功。任何帮助将不胜感激。

最佳答案

首先我们可以将类型概括为以下:

nubTuples :: Eq a => [(a,a)] -> [(a,a)]

但是,为了使事情变得高效和简单,我们还为 a 请求一个 Ord 实例。为什么这会让事情变得更容易?因为现在我们可以将元组转换为有序的范式。然后我们可以简单地 nub 。排序。下面的实现实际上只是基于该表示进行排序和结点,因此 nubTuples [(2,1)] = [(2,1)] 而不是 [(1,2)]

import Data.List (sortOn, nubBy)
import Data.Tuple (swap)

nubTuples :: Ord a => [(a,a)] -> [(a,a)]
nubTuples = nubBy unorderedCompare . sortOn orderTuple
  where orderTuple (x,y)
          | x < y = (x,y)
          | otherwise = (y,x)
        unorderedCompare x y = x == y || swap x == y

请注意,这会更改顺序并删除重复项:

nubTuples [(3,4),(1,2),(1,2)] = [(1,2),(3,4)]

至于更改顺序,我们可以使用 discriminationData.Discrimination 中的 nubWith 函数来解决这个问题。包裹。那么我们的代码就会变成下面这样:

 import Data.Discrimination (nubWith, Grouping)

 nubTuples :: (Ord a, Grouping a) => [(a,a)] -> [(a,a)]
 nubTuples = nubWith orderTuple
   where orderTuple (x,y)
           | x < y = (x,y)
           | otherwise = (y,x)

这不需要排序,保持顺序不变并且最大限度地惰性(这通常对性能非常重要)。尽管如此,它仍然会删除重复项。

您可以像这样简单地为您的任何类型派生一个 Grouping 实例:

{-# LANGUAGE DeriveGeneric #-}
import Data.Discrimination
import GHC.Generics

data A = A deriving Generic
instance Grouping A

请注意,没有用于四元组的 Grouping 实例。这将是一种解决方法:

nubFourTuples :: (Grouping a, Ord a, Grouping b, Ord b,
                  Grouping c, Ord c, Grouping d, Ord d)
              => [((a,b,c,d),(a,b,c,d))] -> [((a,b,c,d),(a,b,c,d))]
nubFourTuples = (fmap . both) reassociate . nubTuples . (fmap . both) associate
   where associate (w,x,y,z) = ((w,x),(y,z))
         reassociate ((w,x),(y,z)) = (w,x,y,z)
         both f (x,y) = (f x, f y)

关于list - 从 Haskell 的列表中删除共轭元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41026518/

相关文章:

list - 如何合并多个文本文件、删除重复行并将剩余行分割成一定长度的多个文件?

haskell - 带防护功能 : syntax error when using "where"

haskell - 混合 MonadIO、MonadState 和缩放时出现 "Could not deduce"错误

python - 如何在 Python 中创建一个空元组的元组?

reference - 将元组引用的迭代器解压缩到两个引用集合中

Python - 从数组中获取最频繁的元素/将 numpy 数组转换为 std 数组

c# - 收集的真实枚举器是如何实现的?

C# 数据结构,可以动态调整大小到给定限制的列表,并允许快速访问任何索引

Haskell 文本包选择

闭包中的 Swift 映射元组