2016-12-16 2 views
1

J'écris actuellement une fonction dans Erlang, qui nécessite des binaires qui n'ont pas de zéros de fin. En raison de la mise en œuvre, et d'autres entrées, les éléments qui seront retournés auront des zéros de fin.Bande de fin de queue dans un binaire dans Erlang

En d'autres termes, je vais avoir des choses telles que:

<<1,2,3,0,0>> et <<3,1,0,2,4,5,0,0,2,3,4,0,0,0,0,0>>

Pour ce qui précède, je dois obtenir:

<<1,2,3>> et <<3,1,0,2,4,5,0,0,2,3,4>>

Zéros avant la les zéros continus à la fin doivent être conservés.

Si quelqu'un pouvait donner une solution, ce serait grandement apprécié. Je vous remercie!

Répondre

1

La façon simple et directe serait quelque chose comme:

1> Binary = <<3,1,0,2,4,5,0,0,2,3,4,0,0,0,0,0>>. 
<<3,1,0,2,4,5,0,0,2,3,4,0,0,0,0,0>> 
2> list_to_binary(lists:reverse(lists:dropwhile(fun(0) -> true; (_) -> false end, lists:reverse(binary_to_list(Binary))))). 
<<3,1,0,2,4,5,0,0,2,3,4>> 

Je le recommande le profilage des données réalistes pour voir si ça va marcher pour vous.

+0

Merci, ce * fait * travail. – caluga

+0

Aussi, je compris que je pouvais utiliser aussi ceci: garniture (A) -> \t cas binaire: à (A, byte_size (A) - 1) == 0 \t \t vrai -> trim (binaire: partie (A, {0, octet_size (A) -1})); \t \t false -> A \t fin. Ce qui signifie pas besoin de convertir en liste et retour. Quoi qu'il en soit, tout est résolu, merci! – caluga

+1

C'est vrai, mais votre manière fait aussi beaucoup d'opérations inutiles et crée beaucoup d'ordures qui doivent être nettoyées. Tant que les binaires avec lesquels vous traitez sont petits et n'ont pas beaucoup de 0, tout ira bien, mais vous avez vraiment besoin de profiler les deux façons avec des données réelles avant de les mettre dans un vrai système. Btw, votre chemin échoue également sur les binaires vides ou les binaires contenant tous les 0. –

1

Une solution que j'ai rassemblée avant de remarquer celle de @ caluga dans un commentaire. Celui-ci gère les binaires vides ou tous les zéros.

strip(B) -> 
    strip(B, erlang:byte_size(B) - 1). 

strip(_B, -1) -> 
    <<>>; 
strip(B, Idx) -> 
    case binary:at(B, Idx) of 
    0 -> strip(B, Idx - 1); 
    _ -> binary:part(B, 0, Idx + 1) 
    end. 


1> demo:strip(<<>>). 
<<>> 
2> demo:strip(<<0>>). 
<<>> 
3> demo:strip(<<0,0>>). 
<<>> 
4> demo:strip(<<1,2>>). 
<<1,2>> 
5> demo:strip(<<1,0,2>>). 
<<1,0,2>> 
6> demo:strip(<<1,0,2,0>>). 
<<1,0,2>> 
7> demo:strip(<<1,0,2,0,0>>). 
<<1,0,2>> 
0

Vous pouvez utiliser cette fonction simple:

-module(strip). 

-export([trailing0/1]). 

trailing0(B) when is_binary(B) -> 
    S = byte_size(B) - 1, 
    case B of 
     <<Prefix:S/bytes, 0>> -> trailing0(Prefix); 
     _ -> B 
    end; 
trailing0(B) -> error(badarg, [B]). 

Si vous prévoyez de longues suffixes, vous pouvez utiliser ceci:

trailing0(B) when is_binary(B) -> 
    S = byte_size(B) - 1, 
    S2 = S - 7, 
    case B of 
     <<Prefix:S2/bytes, 0:64>> -> trailing0(Prefix); 
     <<Prefix:S/bytes, 0>> -> trailing0(Prefix); 
     _ -> B 
    end; 
trailing0(B) -> error(badarg, [B]).