lis*_*tor 8 comparison set elements perl6
Perl6文档表明,当比较一组中的两个项目时,===
使用.这是来自perl6文档的引用:
允许任何类型的对象/值作为设置元素.在集合中,每个元素都保证是唯一的(在某种意义上,没有两个元素会与
===
运算符进行正比较)
我想知道是否可以使用用户定义的函数而不是===
?例如,我如何使用~~
而不是===
确定集合中的2个元素是否"相等".
我试图解决的问题是:集合A有一些名字和一些姓氏,但是所有的小写和没有标点符号,而集合B有许多名字和姓氏以任何顺序混合,并且那里可能是名称附带的标点符号,可能是大写或小写.我想知道集合A中的人(表示为具有一个特定名字和姓氏的A的子集)是否出现在集合B中.在这种情况下,===
由于集合B中的字母案例和标点符号,我无法使用.
如果我可以使用~~
而不是===
,那么问题就会简单得多,因为我只需要确定A的子集是否也是B的子集~~
.这类似于我之前提到的"置换匹配"问题.
非常感谢你 !
有几种方法,我将从简单/慢速的方式开始.我将使用==
运算符,但您可以使用任何操作.如果你想迭代列表/集合,你可以使用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
Run Code Online (Sandbox Code Playgroud)
您需要通过基准测试来了解这是否与以更传统的方式检查集合成员资格一样快.对于大型集合,传统方式应该更快,因为可以使用散列查找.在某些编程语言中,迭代比散列更快,直到列表变得非常大.
如果您不需要获取匹配元素,则可以使用联结,它将并行执行多个检查:
say so ("3", "4").any() == 4; # True
Run Code Online (Sandbox Code Playgroud)
您也可以使用联结进行子集测试,但由于这是一个O(m*n)操作(尽管是自动线程),因此在比较两个非常大的集合时不要期望高性能.
say so (2, 3).all() == ('1', '2', '3').any(); # True
say so (2, 3, 4).all() == ('1', '2', '3').any(); # False
Run Code Online (Sandbox Code Playgroud)
我使用了列表而不是上面的集合,因为如果你没有使用标准的运算符/方法,那么集合就不会提供速度或API优势.