【问题标题】:Functionally comparing data sets to each other once with Haskell使用 Haskell 在功能上将数据集相互比较一次
【发布时间】:2012-11-13 17:20:10
【问题描述】:

经过一年多的心理争论,我终于对 Haskell 有了足够的了解,可以将其视为满足我大多数一般编程需求的主要语言。我非常喜欢它。

但我仍然在努力以一种功能性的方式进行非常具体的操作。

一个简化的例子:

Set = [("Bob", 10), ("Megan", 7), ("Frank", 2), ("Jane", 11)]

我想将这些条目相互比较。对于像 C 或 Python 这样的语言,我可能会创建一些复杂的循环,但我不确定哪种方法(映射、折叠、列表理解?)对于函数式语言来说是最好的或最有效的。

这是我开始编写的代码示例:

run xs = [ someAlgorithm (snd x) (snd y) | x <- xs, y <- xs, x /= y ]

谓词阻止列表推导将条目与其自身进行比较,但该函数效率不高,因为它比较已经比较过的条目。例如。它会将 Bob 与 Megan 进行比较,然后将 Megan 与 Bob 进行比较。

任何有关如何解决此问题的建议将不胜感激。

【问题讨论】:

  • 你说你想比较它们,但不是你想用比较的结果做什么。从您的示例中,您似乎想查看列表中两个不同元素的每一个选择。是这样吗?
  • 是的,但不是“反向”选择。我想比较鲍勃和梅根,鲍勃和弗兰克,鲍勃和简,然后是梅根和弗兰克,梅根和简,然后是弗兰克和简(我认为这涵盖了所有组合)。这看起来可以用 fold 完成,但我不确定。

标签: performance haskell functional-programming dataset comparison


【解决方案1】:

如果您对您的数据类型有一个排序,您可以只使用x &lt; y 而不是x /= y

另一种方法是使用tails 来避免比较相同位置的元素:

[ ... | (x:ys) <- tails xs, y <- ys]

这具有仅选择原始列表中x 之后出现的项目y 的效果。如果您的列表包含重复项,您需要将其与之前的显式过滤相结合。

【讨论】:

  • OP 似乎想查看所有对,忽略顺序,所以我认为排序没有帮助——这似乎是一个必然的 n**2 问题。 +1 为尾巴的建议,我认为这是正确的答案。
  • @JameySharp:是的,我对那个有点放屁。已经删除了那部分:)
  • 如此简洁的解决方案!非常感谢您的时间和帮助。
  • 应该注意的是,模式(x:ys) &lt;- tails xs 在遇到tails xs 的最后一个元素(@987654329)时会失败,这不是 错误,而是有意为之@。在列表推导中,模式匹配失败不是错误,而是导致元素被跳过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
  • 2013-02-26
  • 2016-07-03
  • 2013-01-24
  • 2017-06-07
  • 1970-01-01
  • 2023-01-12
相关资源
最近更新 更多