perl 6 集合操作中用户定义的比较函数
perl6 User-defined comparison function in set opertions
Perl6 文档指出,当比较一组中的两个项目时,使用 ===
。这是 perl6 文档中的引用:
Objects/values of any type are allowed as set elements. Within a Set,
every element is guaranteed to be unique (in the sense that no two
elements would compare positively with the ===
operator)
我想知道是否可以使用用户定义的函数来代替 ===
?例如,如何使用 ~~
而不是 ===
来确定集合中的 2 个元素是否为 "equal"。
我要解决的问题是:集合 A 有一些名字和一些姓氏,顺序不限,但全部小写且没有标点符号,集合 B 有一些名字和姓氏混合在一起任何顺序,并且名称可能带有标点符号,并且可以是大写或小写。我想知道集合 A 中的某个人(表示为具有特定名字和姓氏的 A 的子集)是否出现在集合 B 中。在这种情况下,我不能使用 ===
因为字母大小写和标点符号设置 B.
如果我可以使用~~
而不是===
,问题会简单很多,因为我只需要使用[=13=来确定A的子集是否也是B的子集].这类似于我之前提到的 "permutation match" 问题。
非常感谢!
有几种方法,我将从 easy/slow 方法开始。我将使用 ==
运算符,但您可以使用任何运算符。如果您想遍历 list/set,您可以将 first
与您喜欢的任何匹配逻辑一起使用,然后检查 .defined
以确认您获得了匹配。 (如果你想非常小心或者如果你的列表包含未定义的项目,你应该使用 :p
副词所以你的输出是一个 key/value 对,当且仅当某些匹配元素时才会定义找到了。)
对于使用此技术进行草率匹配的示例,我将在列表和集合中搜索一个数字 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
您必须进行基准测试才能知道这是否与以更传统的方式检查集合成员一样快。对于大型集合,常规方法应该更快,因为可以使用散列查找。在某些编程语言中,迭代比哈希更快,直到列表变得非常大。
如果不需要获取匹配的元素,可以使用junctions,它会并行做多个检查:
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
我在上面使用列表而不是集合,因为如果您不使用标准 operators/methods,集合将不会提供任何速度或 API 优势。
Perl6 文档指出,当比较一组中的两个项目时,使用 ===
。这是 perl6 文档中的引用:
Objects/values of any type are allowed as set elements. Within a Set, every element is guaranteed to be unique (in the sense that no two elements would compare positively with the
===
operator)
我想知道是否可以使用用户定义的函数来代替 ===
?例如,如何使用 ~~
而不是 ===
来确定集合中的 2 个元素是否为 "equal"。
我要解决的问题是:集合 A 有一些名字和一些姓氏,顺序不限,但全部小写且没有标点符号,集合 B 有一些名字和姓氏混合在一起任何顺序,并且名称可能带有标点符号,并且可以是大写或小写。我想知道集合 A 中的某个人(表示为具有特定名字和姓氏的 A 的子集)是否出现在集合 B 中。在这种情况下,我不能使用 ===
因为字母大小写和标点符号设置 B.
如果我可以使用~~
而不是===
,问题会简单很多,因为我只需要使用[=13=来确定A的子集是否也是B的子集].这类似于我之前提到的 "permutation match" 问题。
非常感谢!
有几种方法,我将从 easy/slow 方法开始。我将使用 ==
运算符,但您可以使用任何运算符。如果您想遍历 list/set,您可以将 first
与您喜欢的任何匹配逻辑一起使用,然后检查 .defined
以确认您获得了匹配。 (如果你想非常小心或者如果你的列表包含未定义的项目,你应该使用 :p
副词所以你的输出是一个 key/value 对,当且仅当某些匹配元素时才会定义找到了。)
对于使用此技术进行草率匹配的示例,我将在列表和集合中搜索一个数字 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
您必须进行基准测试才能知道这是否与以更传统的方式检查集合成员一样快。对于大型集合,常规方法应该更快,因为可以使用散列查找。在某些编程语言中,迭代比哈希更快,直到列表变得非常大。
如果不需要获取匹配的元素,可以使用junctions,它会并行做多个检查:
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
我在上面使用列表而不是集合,因为如果您不使用标准 operators/methods,集合将不会提供任何速度或 API 优势。