Perl6文档表明,在比较集合中的两个项目时,使用===
。这是来自perl6文档的引用:
允许任何类型的对象/值作为设置元素。在一个集合中, 每个元素都保证是独一无二的(从某种意义上说,没有两个元素 元素将与
进行积极比较===
运算符
我想知道是否可以使用用户定义的函数而不是===
?例如,如何使用~~
代替===
来确定集合中的2个元素是否等于"。
我试图解决的问题是:集合A有一些名字和一些姓氏,但是所有的小写和没有标点符号,而集合B有许多名字和姓氏以任何顺序混合,名称可能附有标点符号,可能是大写或小写。我想知道集合A中的人(表示为具有一个特定名字和姓氏的A的子集)是否出现在集合B中。在这种情况下,由于字母案例和标点符号,我无法使用===
设置B.
如果我可以使用~~
代替===
,则问题会更加简单,因为我只需要使用~~
确定A的子集是否也是B的子集。这类似于"排列匹配"我之前提到的问题。
非常感谢!
答案 0 :(得分: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优势。