Enums Elixir删除嵌套元素
我得到了一个带有映射和数组的嵌套结构,我想保留嵌套数组的第一个元素Enums Elixir删除嵌套元素,enums,nested,elixir,Enums,Nested,Elixir,我得到了一个带有映射和数组的嵌套结构,我想保留嵌套数组的第一个元素Enum.at(0)。 我希望保留大部分结构,并用其中的第一个元素替换嵌套数组。假设我有一个基本数组oldstruct,它包含一个数组a,它本身包含一个数组b。我想删除a中除第一项之外的所有项,并对a中的数组b执行相同操作。在JS中,我会使用以下代码: var newStruct = []; for (var i = 0; i < oldstruct.length; i++) { newStruct.push(oldSt
Enum.at(0)
。
我希望保留大部分结构,并用其中的第一个元素替换嵌套数组。假设我有一个基本数组oldstruct
,它包含一个数组a
,它本身包含一个数组b
。我想删除a
中除第一项之外的所有项,并对a
中的数组b
执行相同操作。在JS中,我会使用以下代码:
var newStruct = [];
for (var i = 0; i < oldstruct.length; i++) {
newStruct.push(oldStruct[i]);
newStruct[i].a = [];
newStruct[i].a.push(oldStruct[i].a[0]);
newStruct[i].a[0].b = [];
newStruct[i].a[0].b.push(oldStruct[i].a[0].b[0]);
}
我想要的是:
[%Chat.Chat{ chat_users: [%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text}]}],
{other_property: ...}},
%Chat.Chat{ chat_users: [%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text}]}],
{other_property: ...}}]
我得到的是:
[%Chat.Chat{ chat_users: [%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text}]},
%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text}],
{other_property: ...}}]},
%Chat.Chat{ chat_users: [%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text}]},
%Chat.ChatUser{
chat_messages: [%Chat.ChatMessage{text: "some text},
%Chat.ChatMessage{text: "some text}],
{other_property: ...}}]}]
因此,根据我的实际结构:我得到了一个带有一些属性的聊天数组,一个带有chatuser的数组和一个每个chatuser都有chat_消息的数组,我希望保留第一个chatuser和第一个chatmessage给保留的chatuser
采用Igor答案后的解决方案:
|> Enum.map(fn chat ->
Map.update!(chat, :chat_users, fn chat_users ->
case Enum.at(chat_users, 0) do
nil -> nil
_ ->
chat_user =
chat_users
|> List.first
|> Map.update!(:chat_messages, & [List.first(&1)])
[chat_user]
end
end)
end)
假设您有以下结构,满足您的描述:
initial = [
%{a: [%{b: [1,2,3]}, 1], c: 0 },
%{a: [%{b: [1,2,3]}, 1], c: 0 },
%{a: [%{b: [1,2,3]}, 1], c: 0 },
%{a: [%{b: [1,2,3]}, 1], c: 0 },
]
我们希望在:a
和:b
键下只包含列表的第一个元素
然后,Elixir中的以下行解决了问题:
final =
initial
|> Enum.map(fn map_with_a ->
Map.update!(map_with_a, :a, fn list_with_bs ->
map_with_b =
list_with_bs
|> List.first
|> Map.update!(:b, & [List.first(&1)])
[map_with_b]
end)
end)
IO.puts(inspect(final))
只需迭代列表并使用函数更新映射值
输出为:
[
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0}
]
假设这组数据,类似于Igor的示例:
initial = [
%{a: [%{b: [1,2,3]}, 1], c: 0 },
%{a: [%{b: [1,2,3]}, 1], c: 0 },
%{a: [%{b: [1]}, 1], c: 0 },
%{a: [%{b: []}, 1], c: 0 },
]
另一种可能是利用传递给Enum.map
的匿名函数上的多个函数头,尽管根据口味可能可读性稍差:
Enum.map(initial, fn
(%{a: [%{b: [h | _]} | _]} = element) -> Map.put(element, :a, [%{b: [h]}])
(%{a: _} = element) -> Map.put(element, :a, [])
(element) -> element
end)
[
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [], c: 0}
]
这是一个将函数作为键的完美用例(感谢@igor drozdov提供的初始数据):
获取和更新(
首字母,
[Access.all(),:a,
fn:get_和_update,[%{b:[h | |]}| tail],_next->
{h,[%{b:[h]}| tail]}
(完),,
& &1)
#⇒ {[1, 1, 1, 1],
# [
#%{a:[%{b:[1]},1],c:0},
#%{a:[%{b:[1]},1],c:0},
#%{a:[%{b:[1]},1],c:0},
#%{a:[%{b:[1]},1],c:0}
# ]}
非常强大,在这种情况下,它通常会淘汰通用映射器。您能用Elixir语法发布一个示例输入和预期输出吗?这看起来像我想要的。我编辑了我的文章,以提供我正在研究的结构。似乎在更新!他做这项工作。THX:)和
IO.puts(检查(最终))
对我来说是新的。我总是使用带有标签的inspectIO.inspect(final,标签:“我的最终结果!!!”)
作为测试中的控制台输出。学习新东西总是很好:)哦,从没听说过Access
。看起来很有趣。将需要一些时间来理解代码的工作方式;)。我修改了代码并拥有|>Enum.map(fn%{chat_用户:[%{chat_消息:chat_消息}=first_chat_用户| rest]}=chat->%{chat| chat_用户:[%{first_chat_用户| chat_消息:List.first(chat_消息)}}}}其他->另一端)
。将尝试访问,因为我以前从未使用过它。谢谢
Enum.map(initial, fn
(%{a: [%{b: [h | _]} | _]} = element) -> Map.put(element, :a, [%{b: [h]}])
(%{a: _} = element) -> Map.put(element, :a, [])
(element) -> element
end)
[
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [%{b: [1]}], c: 0},
%{a: [], c: 0}
]