在 Erlang 中将元组与无关变量进行匹配
我正在寻找一种使用部分元组在 Erlang 中的列表中查找元组的方法,类似于 Prolog 中的函子匹配。例如,我想使用以下代码返回 true
:
member({pos, _, _}, [..., {pos, 1, 2}, ...])
由于以下错误,该代码无法立即工作:
variable '_' is unbound
有没有一种简单的方法可以达到相同的效果?
I am looking for a way to find tuples in a list in Erlang using a partial tuple, similarly to functors matching in Prolog. For example, I would like to following code to return true
:
member({pos, _, _}, [..., {pos, 1, 2}, ...])
This code does not work right away because of the following error:
variable '_' is unbound
Is there a brief way to achieve the same effect?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于简单的情况,最好使用已经提到的 lists:keymember/3。但如果你确实需要
member
函数,你可以自己实现它,如下所示:示例:
For simple cases it's better to use already mentioned lists:keymember/3. But if you really need
member
function you can implement it yourself like this:Example:
使用 lists:keymember/3 代替。
Use lists:keymember/3 instead.
您可以使用列表理解通过宏来完成此操作:
它不是很有效(它贯穿整个列表),但它是我能想到的最接近原始语法的。
如果您想实际提取匹配的元素,只需删除“length”并添加一个变量:
You can do it with a macro using a list comprehension:
It is not very efficient (it runs through the whole list) but it is the closest I can think to the original syntax.
If you want to actually extract the elements that match you just remove 'length' and add a variable:
您可以使用列表理解来做到这一点:
Matches = [ Match || {Prefix, _, _} = 匹配 <- ZeList, Prefix == pos].
You could do it using list comprehension:
Matches = [ Match || {Prefix, _, _} = Match <- ZeList, Prefix == pos].
另一种可能性是执行匹配规范的操作并使用原子
'_'
而不是原始_
。然后,您可以编写一个类似于以下内容的函数:然后,您的调用现在将是:
这不会让您匹配像
{A, A, '_'}
这样的模式(检查第一个两个元素是相同的),但如果您不需要变量,这应该可以工作。您还可以将其扩展为使用类似语法的变量来匹配规范(
'$1'
、'$2'
等),但需要做更多工作 - 添加第三个将参数传递给is_match
以及您目前看到的变量绑定,然后为它们编写类似于'_'
子句的函数子句。当然,这不是最快的方法。需要注意的是,我还没有实际测量过,我希望在使用 fun 的语言中使用模式匹配会带来更好的性能,尽管它确实使调用站点更加冗长。这是您必须考虑的权衡。
Another possibility would be to do what match specs do and use the atom
'_'
instead of a raw_
. Then, you could write a function similar to the following:Then, your call would now be:
This wouldn't let you match patterns like
{A, A, '_'}
(checking where the first two elements are identical), but if you don't need variables this should work.You could also extend it to use variables using a similar syntax to match specs (
'$1'
,'$2'
, etc) with a bit more work -- add a third parameter tois_match
with the variable bindings you've seen so far, then write function clauses for them similar to the clause for'_'
.Granted, this won't be the fastest method. With the caveat that I haven't actually measured, I expect using the pattern matching in the language using a fun will give much better performance, although it does make the call site a bit more verbose. It's a trade-off you'll have to consider.
可以使用
ets:match
:May use
ets:match
: