2

次の関数をよりエレガントなものに置き換えようとしています:

split_packet(_, <<>>) ->
    [];
split_packet(Size, P) when byte_size(P) < Size ->
    [ P ];
split_packet(Size, P) ->
    {Chunk, Rest} = split_binary(P, Size),
    [ Chunk | split_packet(Size, Rest) ].

(私は今、これは末尾再帰ではありません -- シンプルに保ちたかったのですが、Erlang の新しいバージョンではパフォーマンスが問題にならないことに加えて)

出力例:

1> split_packet(3, <<1,2,3,4,5,6,7,8>>).
[<<1,2,3>>,<<4,5,6>>,<<7,8>>]

リスト内包表記を使用したエレガントなソリューションが望ましいでしょう。これは、この結果がリスト内包表記でさらに処理され、1 つの内包表記にラップできるためです。

私は試した

[ X || <<X:Size/binary>> <= P ].

ただし、Size が の倍数でない場合、これは最後のチャンクを除外しますbyte_site(P)

2>  [ X || <<X:3/binary>> <= <<1,2,3,4,5,6,7,8>> ].
[<<1,2,3>>,<<4,5,6>>]
4

3 に答える 3

4

率直に言って、私はあなたの現在のバージョンに大きな問題があるとは思いません. あなたが述べているように、最後のフラグメントが破棄されるため、バイナリ/リスト内包表記ではそれを行うことはできません。

私が考えることができる唯一のことは、最初に最も頻繁なケースに一致するように句を並べ替えることです:

split_packet(Size, P) when byte_size(P) >= Size->
    {Chunk, Rest} = split_binary(P, Size),
    [Chunk|split_packet(Size, Rest)];
split_packet(_Size, <<>>) ->
    [];
split_packet(_Size, P)  ->
    [P].
于 2011-05-04T09:17:36.130 に答える
2

もう少し効率的なオリジナルのバリエーション:

split_packet(Size, Data) when Size > 0 ->
    case Data of
        <<Packet:Size/binary, Rest/binary>> ->
            [Packet | split_packet(Size, Rest)];
        <<>> ->
            [];
        _ ->
            [Data]
    end.
于 2011-05-04T19:36:43.287 に答える
2

入力バイナリを でパディングし(Size - (byte_size(Binary) rem Size)) * 8、リスト内包表記で実行することができます[ X || <<X:Size/binary>> <= P ]

Y = (Size - (byte_size(Binary) rem Size)) * 8

[ X || << X:3/binary >> <= << Binary/binary , 0:Y >> ]

そして、最後のセグメントから余分なビットを切り刻みます..

于 2011-05-04T09:31:11.950 に答える