String.to_integer / 1的奇怪行为

时间:2015-08-31 04:05:41

标签: elixir

Elixir中String.to_integer有一些奇怪的东西。没什么大不了的,但我想知道是否有办法用管道操作员链接我的所有功能。

这是问题所在。这行代码(你可以试试“iex”):

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1))

返回字符串"3765"

我想要的是一个整数。所以我只需要在前一个语句的末尾添加这段代码|> String.to_integer,我应该有一个整数。我们试试吧。这段代码:

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1)) 
|> String.to_integer

告诉我:"3765"。不是整数,一个字符串!

如果我这样做:

a = [5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1)) 
String.to_integer(a)

它返回一个整数:3765

这就是我现在正在做的事情,但它让我很生气,因为我很乐意将所有这些功能与惊人的管道操作员联系起来。

感谢您的帮助或灯光。 Elixir非常有趣!

1 个答案:

答案 0 :(得分:9)

您需要在map_join的参数周围添加括号。目前,您的代码被解释为

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &(Integer.to_string(&1) |> String.to_integer))

你想要的是什么

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &(Integer.to_string(&1)))
|> String.to_integer

通常,在管道内使用捕获时,总是需要使用括号来避免歧义。捕获也可以简化为&Integer.to_string/1

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &Integer.to_string/1)
|> String.to_integer

但普通的Enum.join会做同样的事情。如果您查看the implementation,它会使用the String.Chars protocol将整数转换为字符串。

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.join
|> String.to_integer

顺便说一下,你可以在不使用字符串的情况下实现同样的目的:

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.reduce(0, &(&2 * 10 + &1))

哦,然后有Integer.digitsInteger.undigits,可用于将整数转换为数字列表。它在当前版本中不存在,但它位于1.1.0-dev分支中,所以我怀疑它会出现在1.1.0中。您可以观看进度here

[5, 6, 7, 3] 
|> Enum.reverse 
|> Integer.undigits