perl 6集合操作中用户定义的比较函数

问题描述 投票:8回答:1

Perl6文档表明,当比较一组中的两个项目时,使用===。这是来自perl6文档的引用:

允许任何类型的对象/值作为设置元素。在一个集合中,每个元素都保证是唯一的(在某种意义上,没有两个元素会与===运算符进行正向比较)

我想知道是否可以使用用户定义的函数而不是===?例如,我如何使用~~而不是===来确定集合中的2个元素是否“相等”。

我试图解决的问题是:集合A有一些名字和一些姓氏,但是所有的小写和没有标点符号,而集合B有许多名字和姓氏以任何顺序混合,并且那里可能是名称附带的标点符号,可能是大写或小写。我想知道集合A中的人(表示为具有一个特定名字和姓氏的A的子集)是否出现在集合B中。在这种情况下,由于集合B中的字母大小写和标点符号,我不能使用===

如果我可以使用~~而不是===,那么问题会更加简单,因为我只需要确定A的子集是否也是使用~~的B的子集。这类似于我之前提到的“置换匹配”问题。

非常感谢你 !

set comparison elements perl6
1个回答
5
投票

有几种方法,我将从简单/慢速的方式开始。我将使用==操作符,但您可以使用任何操作。如果你想迭代列表/集合,你可以使用first和你喜欢的任何匹配逻辑,然后检查.defined以确认你有匹配。 (如果你想要非常小心,或者你的列表中包含未定义的项目,你应该使用:p副词,这样你的输出就是一个键/值对,当且仅当找到一些匹配的元素时才会定义。)

对于使用此技术进行草率匹配的示例,我将在列表和IntStr集中搜索数字:

say 4 ∈ ("3", "4"); # False, because the list doesn't contain the integer 4
say ("3", "4").first(* == 4, :p).defined; # True
say set("3", "4").keys.first(* == 4, :p).defined; # True

您需要通过基准测试来了解这是否与以更传统的方式检查集合成员资格一样快。对于大型集合,传统方式应该更快,因为可以使用散列查找。在某些编程语言中,迭代比散列更快,直到列表变得非常大。

如果您不需要获取匹配元素,则可以使用联结,它将并行执行多个检查:

say so ("3", "4").any() == 4; # True

您也可以使用联结进行子集测试,但由于这是一个O(m * n)操作(尽管是自动线程),因此在比较两个非常大的集合时不要期望高性能。

say so (2, 3).all() == ('1', '2', '3').any(); # True
say so (2, 3, 4).all() == ('1', '2', '3').any(); # False

我使用了列表而不是上面的集合,因为如果你没有使用标准的运算符/方法,那么集合就不会提供速度或API优势。

© www.soinside.com 2019 - 2024. All rights reserved.