ERLANG - 模式匹配 [英] ERLANG - Pattern Matching

查看:190
本文介绍了ERLANG - 模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个变量:

  Data = [[< > 
[ <10>,<171>],
[<112>,<Gen20267> ;>],
[<52>,<20100812-06:32:30.687>>]]

我正在尝试为两个具体案例进行匹配。



类似于外部结构 - 简单地说[]
任何内容都会尝试 [_] 但不能去?


$ b $第二,对于一个特定的模式,就像我看到一个<<10>>或<112>>或<52>>那么我是将正确的数据作为一个原子。
基本上,<10>>或<112>>或<52>>是字段,右侧的数据。



我尝试过像 [<10>> _] 仍然没有去的声明



以下是代码的其余部分:

  dataReceived(Message) - > 
收到
{开始} - >
ok;

[_] - > %%否go
io:format(Reply 1 =〜p〜n,[Message]);

[<10>>,_] - > %%否go
io:format(Reply 1 =〜p〜n,[Message])


end。

作为一个注释,消息不是作为元组发送,正如Data =



任何人都可以带领我走向正确的方向吗?



谢谢和晚安!
-B



更新



温暖,我必须模拟匹配任何进来。



所以如果我说

 code> Message = = [[<>]>],
[<10>,<171>
[<112>,<Gen20267>>>],
[<52> ;20100812-06:32:30.687>>]]

我正在寻找模式匹配字段<112>>



如112总是会说112,但Gen2067可以随时改变...数据,它将被存储在变量中。

  loop() - > 
收到
[_,[<112>,数据],_]当is_list(X) - > %%匹配另一个列表。
?DEBUG(有一个列表〜p〜n,[X]),
loop();
_Other - >
?DEBUG(我不明白〜p〜n,[_Other]),
loop()
结束。

我觉得很接近,但不是100%



-B

解决方案

更新 OP正在尝试将参数传递给函数,发送消息。



由于名称表示接收块用于接收和处理发送到进程的消息。当您使用参数调用 dataReceived 时,它会继续等待消息。由于没有发送消息,它将继续等待。给定当前的代码,如果你想要做某事,那么你必须生成函数,获取进程ID,然后发送一个消息到进程ID。



您可能需要一个函数,其中参数与模式匹配,而不是消息



这样的东西:

  data_Received([Message])当is_list(Message) - > ; 
io:format(Got a list as arg〜p〜n,[Message]);
dataReceived(_Other) - >
io:format(未知arg〜p〜n,[_Other])。

在旁边注释您的第三个模式 [X]当is_list(X) 将永远不会匹配,因为第二种模式是第三种模式的超集。任何匹配 [X]当is_list(X)将始终匹配 [X] ,因此您的第三个匹配条款将不要触发。



原始答案



我不知道我明白你的题。你试图向函数发送消息,还是传递一个参数?



这是有关如何匹配列表列表的部分答案,以防您发送邮件

  -module(mtest)。 
-export([run / 0])。

-ifdef(debug)。
-define(DEBUG(Format,Args),io:format(Format,Args))。
-else。
-define(DEBUG(Format,Args),void)。
-endif。

loop() - >
收到
[X]当is_list(X) - > %%匹配另一个列表。
?DEBUG(有一个列表〜p〜n,[X]),
loop();
_Other - >
?DEBUG(我不明白〜p〜n,[_Other]),
loop()
结束。

查看收到的第一个子句块。 [X]当is_list(X)将内部列表绑定到名称 X 时。我测试了它提供的价值数据,它的工作。

  %%从shell。 
1> c(mtest,{d,debug})。
{ok,mtest}
2> Pid = mtest:run()。
<0.40.0>
3> Data = [[<>>,<171>],[<112> ,],],],],[
[[<>>
[<10>,<171>],
[ <112>,<Gen20267>>],
[<52>,<20100812-06 :32:30.687>>]]]
4> id!数据。
[[<>>
[<10>,<171>],
[ <112>,<Gen20267>>],
[<52>,<20100812-06 :32:30.687>>]]]
得到一个列表[<>>
[<10> 171>],
[<112>,<Gen20267>>>>>>>> >>,<20100812-06:32:30.687>>]]
5>


I have a variable:

Data = [[<<>>, 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]] 

I am trying to pattern match for two specific cases..

One where anything that resembles the outside structure - simply [] Anything inside goes I have tried [ _ ] but no go?

The Second, for a specific pattern inside, like when I see a <<"10">> or <<"112">> or <<"52">> then I am going to take the right side which is the actual data into an atom. Basically the <<"10">> or <<"112">> or <<"52">> are the fields, the right side the data.

I have tried statements like [<<"10">>, _ ] still no go

Here is the rest of the code:

dataReceived(Message) ->
    receive
        {start} -> 
            ok;

        [ _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message]);

                [<<"10">>, _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message])


    end.

As a note the Message is not sent as a tuple it is exactly like Data =

Can anyone lead me in the right direction?

Thanks and Goodnight! -B

UPDATE

Ok now I think Im getting warmer, I have to pattern match whatever comes in.

So if I had say

Message = = [[<<>>], 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]]

And I was looking to pattern match the field <<"112">>

Such as the 112 is always going to say 112, but the Gen2067 can change whenever to whatever.. its the data, it will be stored in a variable.

loop() ->
receive
    [_,[<<"112">>, Data], _] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

I feel im close, but not 100%

-B

解决方案

Update OP is trying to pass an argument to the function and not send messages.

As the name indicates the receive block is used to receive and process messages sent to a process. When you call dataReceived with an argument it proceeds to wait for messages. As no messages are sent it will continue to wait endlessly. Given the current code if you want it to do something then you'll have to spawn the function, get the process ID and then send a message to the process ID.

You probably need a function where the argument is pattern matched and not messages.

Something like this:

dataReceived([Message]) when is_list(Message) ->
    io:format("Got a list as arg ~p~n", [Message]);
dataReceived(_Other) ->
    io:format("Unknown arg ~p~n", [_Other]).

On a side note your third pattern [X] when is_list(X) will never match as the second pattern is a superset of the third. Anything that matches [X] when is_list(X) will always match [X] and therefore your third match clause will never get triggered.

Original Answer

I am not sure I understand your question. Are you trying to send a message to the function or are you passing it an argument?

This is a partial answer about how to match a list of lists in case you are sending a message.

-module(mtest).
-export([run/0]).

-ifdef(debug).
-define(DEBUG(Format, Args), io:format(Format, Args)).
-else.
-define(DEBUG(Format, Args), void).
-endif.

loop() ->
receive
    [X] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

Take a look at the first clause in the receive block. [X] when is_list(X) will bind the inner list to the name X. I tested it with the value of Data you provided and it worked.

%% From the shell.
1> c(mtest, {d, debug}).
{ok,mtest}
2> Pid = mtest:run().
<0.40.0>
3> Data = [[<<>>, [<<"10">>,<<"171">>], [<<"112">>,<<"Gen20267">>], [<<"52">>,<<"20100812-06:32:30.687">>]]].
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
4> Pid ! Data.
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
Got a list [<<>>,
            [<<"10">>,<<"171">>],
            [<<"112">>,<<"Gen20267">>],
            [<<"52">>,<<"20100812-06:32:30.687">>]]
5> 

这篇关于ERLANG - 模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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