函数参数应适用于字符串和unicode

时间:2019-03-13 11:03:25

标签: elixir

我正在通过

计算字符串中的出现次数
def count(strand,nucleotide) do
Enum.count(String.graphemes(strand),&(&1==List.to_string([nucleotide])))

end

如果我将绞线传递为“ AAA”,则效果很好,但如果我像“ AAA”(即,字符列表)那样传递,则失败。

给我

  

**(FunctionClauseError)String.Unicode.graphemes / 1中没有匹配的函数子句

如何使它也适用于unicode参数

我可以做to_string(strand)使其工作,但是由于它是一个字符列表,为什么我不能简单地做为Enum.count('AAA',&(&1 == 'A'))却返回0呢?

2 个答案:

答案 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 :(得分:1)

您可以使用保护子句来定义处理二进制文件的子句和用于处理字符列表的子句。我认为将核苷酸作为代码点而不是字符列表会更有意义:

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, &(&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(&(&1 == nucleotide))
  end

  def count(strand, <<nucleotide::utf8>>) when is_list(strand) do
    Enum.count(strand, &(&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