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(检查(最终))
对我来说是新的。我总是使用带有标签的inspect
IO.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}
]