我一直在研究Dave Thomas 在Elixir的编程练习.我遇到了一个说写一个函数(caesar由于某种原因被调用)的函数,该函数将charlist和一个整数添加到charlist中的每个元素,如果它超过'z'则循环回'a',所以你应该能够称之为
MyList.caesar('ryvke', 13)
它应该返回一个字符串.
我有一个映射列表并执行添加的函数,但它返回一个charlist,我无法弄清楚如何将其转换为字符串:
defmodule MyList do
def caesar(list, n) do
Enum.map list, &(perform_addition(&1, n))
|> to_charlist
|> to_string
end
defp perform_addition(char_val, n) when char_val < 122 do
char_val + n
end
defp perform_addition(_, n) do
97 + n
end
end
Run Code Online (Sandbox Code Playgroud)
我试过了:
基于最后一个子弹的尝试导致:
MyList.caesar('ryvke', 13)
# => <<127, 194, 134, 194, 131, 120, 114>>
Run Code Online (Sandbox Code Playgroud)
Dog*_*ert 21
要回答标题中的问题:您正在寻找List.to_string/1:
iex(1)> List.to_string([97, 98, 99])
"abc"
Run Code Online (Sandbox Code Playgroud)
您没有为这些参数获取可读字符串的原因是您旋转值的逻辑不正确.以下是如何移动小写字母并将其旋转回来,a如果它穿过z而不接触非小写字母:
# ?a == 97, ?z == 122
defp add(ch, n) when ch in ?a..?z do
rem((ch - ?a + n), 26) + ?a
end
defp add(ch, n) when ch in ?A..?Z do
rem(ch - ?A + shift, 26) + ?A
end
defp add(ch, _), do: ch
Run Code Online (Sandbox Code Playgroud)
有了这个,你只需要在输入charlist上映射函数,然后调用List.to_string/1:
def caesar(list, n) do
list |> Enum.map(&add(&1, n)) |> List.to_string
end
Run Code Online (Sandbox Code Playgroud)
iex(1)> MyList.caesar('ryvke', 13)
"elixr"
Run Code Online (Sandbox Code Playgroud)
(因某种原因称为凯撒)
该算法称为Caesar Cipher.