2 votes

La chaîne de bits Elixir contient une sous-chaîne de bits

J'aimerais vérifier si une longue chaîne de bits contient une autre chaîne de bits. Quelque chose comme :

if MyBitstringModule.contains(<<1, 2, 3, 4, 5>>, <<2, 3, 4>>) do
  # do stuff
end

Si j'avais binaires au lieu de cela, ce serait vraiment facile : je pourrais utiliser les =~ opérateur o Chaîne.contient?/2 . Cependant, ces deux méthodes n'opèrent que sur des binaires et échoueraient donc sur des chaînes de bits dont la taille n'est pas divisible par 8.

Le mieux que j'ai trouvé jusqu'à présent est une correspondance récursive comme celle-ci (qui ne fonctionne pas !), qui semble être un bricolage :

def contains(haystack, needle) when is_bitstring(haystack) and is_bitstring(needle) do
  needle_size = bit_size(needle)
  case haystack do
    <<>> -> false
    <<^needle::size(needle_size), _::bitstring>> -> true
    <<_::size(1), remainder::bitstring>> -> contains(remainder, needle)
  end
end

[Notez que malgré un titre plus ou moins identique, il ne s'agit pas d'un duplicata de cette question -la question liée et sa réponse traitent toutes deux de binaires seulement].

EDIT : Mon cas de test ci-dessus était mauvais, puisque les deux arguments sont en fait des binaires. Les meilleurs cas de test sont les suivants :

iex> contains(<<1, 2, 3, 4, 5, 1::size(1)>>, <<2, 3, 4>>)
true
iex> contains(<<1, 2, 3, 4, 5, 1::size(1)>>, <<4, 5, 1::size(1)>>)
true

2voto

Brett Beatty Points 1408

Cela a fonctionné pour moi en ajoutant le bitstring type à votre cas réel

<<^needle::bitstring-size(needle_size), _::bitstring>> -> true

Si vous essayez de le faire correspondre directement

iex> needle = <<3, 4, 5>>
<<3, 4, 5>>
iex> needle_size = bit_size(needle)
24
iex> <<^needle::size(needle_size), _::bitstring>> = <<3, 4, 5>>
** (MatchError) no match of right hand side value: <<3, 4, 5>>
iex> <<^needle::bitstring-size(needle_size), _::bitstring>> = <<3, 4, 5>>
<<3, 4, 5>>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X