如何在 Elixir 中迭代和修改映射内的键值对。示例代码如下。我需要从任何地方删除 c:
how to iterate and modify key-value pair inside map in Elixir. Sample code is below. I need to remove c: from everywhere
** 下面是示例地图,其中有 c: 在一些键的开头,我想要相同的地图,但键中的任何地方都没有 **
map = %{
"soap:Body" => {"c:replyMessage",
%{
"c:ccCaptureReply" => %{
"c:amount" => "100.00",
"c:reasonCode" => "100",
"c:reconciliationID" => "2",
"c:requestDateTime" => "2019-07-10T16:57:49Z"
},
"c:decision" => "ACCEPT",
"c:merchantReferenceCode" => "1255",
"c:purchaseTotals" => {"c:currency", "US"},
"c:reasonCode" => "100",
"c:requestID" => "2",
"c:requestToken" => "FkKZy21",
"xmlns:c" => "urn:schemas-cybersource-com:transaction-data-1.165"
}},
"soap:Header" => {"wsse:Security",
%{
"wsu:Timestamp" => %{
"wsu:Created" => "2019-07-10T16:57:49.246Z",
"wsu:Id" => "Timestamp-90787002",
"xmlns:wsu" => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
},
"xmlns:wsse" => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
}},
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"
}
即使 elixir 核心支持深度遍历,您也有元组作为值并且元组不可迭代。
唯一的方法是编写基于模式匹配的递归解决方案。
defmodule Sanitizer do
def yo(%{} = map) do
map
|> Enum.map(fn
{<<"c:", rest::binary>>, v} -> {rest, yo(v)}
{k, v} -> {k, yo(v)}
end)
|> Map.new()
end
def yo({<<"c:", rest::binary>>, v}), do: {rest, yo(v)}
def yo({k, v}), do: {k, yo(v)}
def yo(any), do: any
end
Sanitizer.yo(map)
#⇒ sanitized result
FWIW,在我认为拥有 leftpad 之类的库就足够好了的时候,我写了一个 Iteraptor
库。如果它没有元组(无论如何都无法遍历),它可以处理输入。
** 下面是示例地图,其中有 c: 在一些键的开头,我想要相同的地图,但键中的任何地方都没有 **
map = %{
"soap:Body" => {"c:replyMessage",
%{
"c:ccCaptureReply" => %{
"c:amount" => "100.00",
"c:reasonCode" => "100",
"c:reconciliationID" => "2",
"c:requestDateTime" => "2019-07-10T16:57:49Z"
},
"c:decision" => "ACCEPT",
"c:merchantReferenceCode" => "1255",
"c:purchaseTotals" => {"c:currency", "US"},
"c:reasonCode" => "100",
"c:requestID" => "2",
"c:requestToken" => "FkKZy21",
"xmlns:c" => "urn:schemas-cybersource-com:transaction-data-1.165"
}},
"soap:Header" => {"wsse:Security",
%{
"wsu:Timestamp" => %{
"wsu:Created" => "2019-07-10T16:57:49.246Z",
"wsu:Id" => "Timestamp-90787002",
"xmlns:wsu" => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
},
"xmlns:wsse" => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
}},
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"
}
即使 elixir 核心支持深度遍历,您也有元组作为值并且元组不可迭代。
唯一的方法是编写基于模式匹配的递归解决方案。
defmodule Sanitizer do
def yo(%{} = map) do
map
|> Enum.map(fn
{<<"c:", rest::binary>>, v} -> {rest, yo(v)}
{k, v} -> {k, yo(v)}
end)
|> Map.new()
end
def yo({<<"c:", rest::binary>>, v}), do: {rest, yo(v)}
def yo({k, v}), do: {k, yo(v)}
def yo(any), do: any
end
Sanitizer.yo(map)
#⇒ sanitized result
FWIW,在我认为拥有 leftpad 之类的库就足够好了的时候,我写了一个 Iteraptor
库。如果它没有元组(无论如何都无法遍历),它可以处理输入。