#elixir
#elixir
Вопрос:
Я подсчитываю количество вхождений в строку с помощью
def count(strand,nucleotide) do
Enum.count(String.graphemes(strand),amp;(amp;1==List.to_string([nucleotide])))
end
Это работает нормально, если я передаю strand как «AAA», но терпит неудачу, если я передаю как «AAA», т.е. charlist.
дает мне
** (FunctionClauseError) в строке нет совпадения с предложением функции.Unicode.graphemes/1
Как я могу заставить это работать и для аргумента unicode
Я могу сделать to_string(strand)
, чтобы заставить это работать, но поскольку это список символов, почему я не могу сделать просто, так как Enum.count('AAA',amp;(amp;1 == 'A'))
он возвращает мне 0
Ответ №1:
Вы сравниваете список с целым числом.
is_list('A') # true
[65] == 'A' # true
[65, 66] = 'AB' # true
[128105, 8205, 128105, 8205, 128103] == '👩👩👧' # true
Вы можете, например, сделать
Enum.count('AAA', fn x ->
[codepoint] = 'A'
x == codepoint
end)
Комментарии:
1. Вероятно, вы хотите сопоставить кодовую точку вне анонимной функции. Таким образом, у вас было бы что-то более похожее на это:
Enum.count('AAA', amp;(amp;1 == codepoint))
или, если функция может принимать кодовую точку, что-то вродеEnum.count('AAA', amp;(amp;1 == ?A))
Ответ №2:
Вы можете использовать предложения guard для определения предложения, которое обрабатывает двоичные файлы, и предложения, которое обрабатывает чарлисты. Я думаю, было бы разумнее передать нуклеотид в качестве кодовой точки, а не списка символов:
defmodule CodepointNucleotide do
def count(strand, nucleotide) when is_binary(strand) do
count(String.to_charlist(strand), nucleotide)
end
def count(strand, nucleotide) when is_list(strand) do
Enum.count(strand, amp;(amp;1 == nucleotide))
end
end
Использование:
iex(1)> CodepointNucleotide.count("AAA", ?A)
3
iex(2)> CodepointNucleotide.count("ABA", ?A)
2
iex(3)> CodepointNucleotide.count('AAA', ?A)
3
iex(4)> CodepointNucleotide.count('ABA', ?A)
2
Вы также могли бы сделать нуклеотид двоичным:
defmodule BinaryNucleotide do
def count(strand, nucleotide) when is_binary(strand) do
strand
|> String.graphemes()
|> Enum.count(amp;(amp;1 == nucleotide))
end
def count(strand, <<nucleotide::utf8>>) when is_list(strand) do
Enum.count(strand, amp;(amp;1 == nucleotide))
end
end
Использование:
iex(5)> BinaryNucleotide.count("AAA", "A")
3
iex(6)> BinaryNucleotide.count("ABA", "A")
2
iex(7)> BinaryNucleotide.count('AAA', "A")
3
iex(8)> BinaryNucleotide.count('ABA', "A")
2