【问题标题】:Safely concatenate elixir list? [duplicate]安全地连接长生不老药列表? [复制]
【发布时间】:2021-08-07 12:38:02
【问题描述】:

如何在 Elixir 中进行nil 列表的安全串联?

我已经通过++提供了一些有关情况和响应的内联示例

看起来nil 在连接时被视为特殊实体。

为什么会这样?

# Append two empty list ✅
iex(1)> [] ++ []
[]
# Append empty list to nil ❌
iex(2)> [] ++ nil
nil # Result should be []
# Append non empty list to nil ❌
iex(3)> [1] ++ nil
[1 | nil] # Result should be [1]
# Append non empty list to nil and enumerate ❌
iex(5)> a = [1, 2] ++ nil
[1, 2 | nil]
iex(6)> Enum.each(a, fn p -> IO.puts(p) end)
1
2
** (FunctionClauseError) no function clause matching in Enum."-each/2-lists^foreach/1-0-"/2
# Add more lists with nil ❌
iex(5)> [1, 2] ++ nil ++ []
** (ArgumentError) argument error

【问题讨论】:

    标签: list elixir concatenation


    【解决方案1】:

    您发现了不正确的列表:最后一个元素的尾部不是 empy 列表的列表。 Listdocumentation中有一个很好的例子:

    常规列表(相当于[1, 2, 3]):

    [1 | [2 | [3 | []]]]
    

    不正确的列表(相当于[1, 2 | 3]):

    [1 | [2 | 3]]
    

    nil 没有什么特别之处 - 任何非列表都会发生同样的事情:

    iex(1)> [1, 2] ++ "foo"
    [1, 2 | "foo"]
    iex(2)> [1, 2] ++ %{3 => 4}
    [1, 2 | %{3 => 4}]
    iex(3)> Enum.each([1,2|"boom"], &IO.puts(&1))
    1
    2
    ** (FunctionClauseError) no function clause matching in Enum."-each/2-lists^foreach/1-0-"/
    

    documentation++

    列表连接运算符。连接一个适当的列表和一个术语, 返回一个列表。

    如果right 操作数不是一个正确的列表,它返回一个不正确的列表 列表。如果 left 操作数不是一个正确的列表,它会引发 ArgumentError.

    来自Enum.each 的错误很奇怪,但似乎也是由期望正确列表的实现引起的。

    我认为这回答了您的问题,但我怀疑它不能解决您的问题。您没有提及为什么您将nil 附加到列表中,也没有提及您想要实现的目标。

    【讨论】:

      【解决方案2】:

      我相信您想要恢复正常、正确的列表。为此,++/2 调用中的两个参数都必须是列表。

      您可能在List.wrap/1 之后为nil

      iex|1 ▸ [] ++ List.wrap([])
      #⇒ []
      iex|2 ▸ [] ++ List.wrap(nil)
      #⇒ []
      iex|3 ▸ [1] ++ List.wrap(nil)
      #⇒ [1]
      iex|4 ▸ [1, 2] ++ List.wrap(nil)
      #⇒ [1, 2]
      iex|5 ▸ [1, 2] ++ List.wrap(nil) ++ [3]
      #⇒ [1, 2, 3]
      iex|6 ▸ [1] ++ List.wrap(2)            
      #⇒ [1, 2]
      

      【讨论】:

        【解决方案3】:

        如果您想消除 nil 部分,则可以对其使用模式匹配。例如:

        defmodule Example do
          def add(list1, list2) do
            case [list1, list2] do
              [nil, nil] -> []
              [nil, list2] -> list2
              [list1, nil] -> list1
              [list1, list2] -> list1 ++ list2
            end
          end
        end
        

        【讨论】:

        • 我的意思是……但是……
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多