perl6设置操作中的用户定义比较功能 [英] perl6 User-defined comparison function in set opertions

查看:80
本文介绍了perl6设置操作中的用户定义比较功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Perl6文档指出,比较一组中的两个项目时,将使用 === 。这是来自perl6文档的报价:

Perl6 documentation indicated that when comparing two items in a set, === is used. This is quote from perl6 documentation:


任何类型的对象/值都可以用作set元素。在Set中,保证
的每个元素都是唯一的(在某种意义上,没有两个
元素会与 === 运算符进行正比较)

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个元素是否相等 。

I am wondering if it is possible to use a user-defined function instead of ===? E.g., How can I use ~~ instead of === in determining whether 2 elements in a set are "equal".

我要解决的问题是:集A具有一些名字和姓氏,但顺序不限,但全部为小写且没有标点符号,而集B具有一定数量的名字和姓氏以任何顺序混合在一起,并且名字后面可能有标点符号,并且可能是大写或小写。我想知道集合A中的人(表示为A的子集,具有一个特定的姓氏和名字)在这种情况下,我不能使用 === 因为B中的字母大小写和标点符号。

The problem I am trying to solve is this: set A has some first names and some last names in any order but all lower case and no punctuation, and set B has a number of first names and last names mixed in any order, and there may be punctuation attached to the names and may be upper or lower cases. I want to know if a person in set A (represented as a subset of A with one specific first and last name) appears in set B. In this case, I cannot use === because of the letter cases and punctuation in set B.

如果我可以使用 ~~ 代替 === ,这个问题会简单得多,因为我只需要使用 ~~ <确定A的子集是否也是B的子集。 / code>。这类似于我之前提到的排列匹配问题。

If I can use ~~ instead of ===, the problem will be much simpler because I only need to determine if a subset of A is also a subset of B using ~~. This is similar to a "permutation match" problem I mentioned before.

非常感谢!

推荐答案

有几种方法,我将从简单/缓慢的方法开始。我将使用 == 运算符,但是您可以使用任何操作。如果要遍历列表/集合,可以先使用 并选择所需的匹配逻辑,然后检查 .defined 确认您有匹配项。 (如果您要非常小心或列表中包含未定义的项目,则应使用:p 副词,以便您的输出为键/值对,并且将

There are a couple ways, and I'll start with the easy/slow way. I'll use the == operator, but you can use any operation. If you want to iterate over the list/set, you can use first with whatever match logic you like, then check for .defined to confirm that you got a match. (If you want to be really careful or if your list contains undefined items, you should use the :p adverb so your output is a key/value pair, and that will be defined if and only if some matching element was found.)

例如,使用此技术的草率匹配示例,我将在列表和集合中搜索一个数字 IntStr

For an example of sloppy matching using this technique, I'll search for a number in a list and set of 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

您必须进行基准测试才能知道这是否与在更多版本中检查集成员身份一样快常规方式。对于大型集合,常规方法应该更快,因为可以使用哈希查找。在某些编程语言中,迭代比散列要快得多,直到列表变得很大为止。

You would have to benchmark to know whether this is as fast as checking set membership in a more conventional way. For a large set, the conventional ways should be faster, since hash lookup can be used. In some programming languages, iteration is faster than hashing until the list gets really big.

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

If you don't need to get the matching element, you can use junctions, which will do multiple checks in parallel:

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

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

And you can use junctions to do subset testing as well, but since this is an O(m*n) operation (despite being auto-threaded), don't expect high performance when comparing two very large sets.

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

我使用列表而不是上面的集合,因为如果您不使用标准运算符/方法,集合没有速度或API优势。

I used lists instead of sets above, since if you're not using the standard operators/methods, sets offer no speed or API advantage.

这篇关于perl6设置操作中的用户定义比较功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆