String 的奇怪行为。to_integer/1

Strange behavior with String.to_integer/1

我在 String.to_integer 的 Elixir 中遇到了一些奇怪的事情。没什么大不了的,但我想知道是否有办法将我的所有功能与管道运算符链接起来。

问题来了。这行代码(你可以在"iex"中试试):

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

returns 字符串 "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)

它returns我一个整数:3765.

这就是我现在正在做的事情,但这让我很生气,因为我很想用神奇的管道运算符以好的方式链接所有这些函数。

感谢您的帮助或点亮。 Elixir 很好玩!

您需要在 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, it will convert the integers to strings anyway, using 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.digits and Integer.undigits, which can be used to convert an Integer to and from a list of digits. It's not present in the current release, though it is in the 1.1.0-dev branch so I suspect it will come in 1.1.0. You can watch the progress here

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