我有一个Elixir Map
:
m1 = %{a: 1, b: "fsfd", c: 123}
我想将其转换为URI
的查询字符串。
a=1&b=fsfd&c=123
我该怎么做?我试过这个:
Enum.reduce(m1, fn({k, v}, acc) -> "#{acc}&{k}=#{v}" end)
但它没有用,因为acc
没有按预期匹配模式。
答案 0 :(得分:2)
您可以使用:
URI.encode_query(%{a: 1, b: 2, c: "fdsfds"})
答案 1 :(得分:0)
您的代码存在的问题是您使用的是Enum.reduce/2
而不是Enum.reduce/3
。您传递的函数在n - 1
中执行reduce/2
次,第一个值用作accumulator
的初始值。
因此,对于您的地图,累加器的初始值将为{:a, 1}
,这是一个不实现String.Chars
协议的元组。您可以通过提供初始累加器值来解决此问题:
Enum.reduce(m1, "", fn({k, v}, acc) -> "#{acc}&{k}=#{v}" end)
<2> Elixir的内置方法:
作为@Dogbert pointed out,您可以使用URI.encode_query/1
而不是自己编写:
iex> URI.encode_query(%{foo: 1, bar: 2, baz: "value with spaces"})
"foo=1&bar=2&baz=value+with+spaces"
答案 2 :(得分:0)
OP的问题有一个简单的示例map
,其中未包含值的集合,因此,如果您要根据URI标准对URI.encode_query(%{a: 1, b: 2})
进行编码,则map
的答案是正确的。 / p>
但是,URI.encode_query/1
不支持具有列表值的地图,并且你们中的很多人将使用Phoenix和/或Plug,因此使用Plug启用了将查询字符串变成{{1} }放入值列表:a[]=1&a[]=2
。对于您来说,有:
[1, 2]