代码之家  ›  专栏  ›  技术社区  ›  xji

在长生不老药中,如何一次处理两个相邻的列表项?

  •  0
  • xji  · 技术社区  · 6 年前

    我想在列表中的每两个相邻项中添加一个字段,以包含彼此的id,即创建一个双链接列表。原因是列表是按特定的数据库查询排序的,我想在某些前端模板中使用此顺序。

    在过程语言中,这是一个简单的for循环,在这里我可以更改 myList[index] myList[index + 1] 在循环体中。

    我想了几种用长生不老药的方法,例如。 chunk_every , zip Enum.with_index 一起 Enum.at 但是到目前为止没有一个是真正令人满意/有效的。

    2 回复  |  直到 6 年前
        1
  •  1
  •   The Brofessor    6 年前

    您可以通过常规链表递归并解构当前头和下一个头。要查找的特殊情况就在基本情况之前(即没有“下一个id”或类似id的项目)。

    例如,如果我们有一个地图列表,比如:

      my_list = [
        %{id: 1, next: nil, previous: nil},
        %{id: 2, next: nil, previous: nil},
        ...
      ]
    
    
      def doubly_link([]), do: []
    
      def doubly_link([head | []]) do
        head = %{head | next: nil}
    
        [head | doubly_link([])]
      end
    
      def doubly_link([head | [next_head | tail]]) do
        head = %{head | next: next_head.id}
        next_head = %{next_head | previous: head.id}
    
        [head | doubly_link([next_head | tail])]
      end
    

    然后打电话 doubly_link(my_list) 会产生:

    [
      %{id: 1, previous: nil, next: 2},
      %{id: 2, previous: 1, next: 3},
      ....,
      %{id: n, previous: prior_to_n_id, next: nil}
    ]
    
        2
  •  1
  •   Aleksei Matiushkin    6 年前

    另一种方法是 Enum.with_index/2

    input = Enum.map(0..4, & %{id: &1})
    head = -1
    tail = Enum.count(input)
    
    input
    |> Enum.with_index(head)
    |> Enum.with_index(head + 2)
    |> Enum.map(fn
      {{value, ^head}, next} ->
        Map.put(value, :next, next)
      {{value, prev}, ^tail} ->
        Map.put(value, :prev, prev)
      {{value, prev}, next} ->
        value
        |> Map.put(:prev, prev)
        |> Map.put(:next, next)
    end)
    
    #⇒ [
    #    %{id: 0, next: 1},
    #    %{id: 1, next: 2, prev: 0},
    #    %{id: 2, next: 3, prev: 1},
    #    %{id: 3, next: 4, prev: 2},
    #    %{id: 4, prev: 3}
    # ]