Functional programming 从列表中删除nils-Erlang

Functional programming 从列表中删除nils-Erlang,functional-programming,erlang,ejabberd,otp,erlang-shell,Functional Programming,Erlang,Ejabberd,Otp,Erlang Shell,如何从列表中删除零,假设我得到: [{“一些”,“其他”,“其他”,无,{“更多”,“更多”,“无,无] 最后,我只想从长元组中提取第一个元素,并将它们放在一个列表中, 比如: [“一些”、“更多”]您可以使用如下函数从列表中删除零: filter_out_nils(Data) when is_list(Data) -> Pred = fun(Element) -> Element /= nil end, lists:filter(Pred, Data). fil

如何从列表中删除零,假设我得到:

[{“一些”,“其他”,“其他”,无,{“更多”,“更多”,“无,无]

最后,我只想从长元组中提取第一个元素,并将它们放在一个列表中, 比如:


[“一些”、“更多”]

您可以使用如下函数从列表中删除零:

filter_out_nils(Data) when is_list(Data) ->
    Pred = fun(Element) -> Element /= nil end,
    lists:filter(Pred, Data). 
filter_out_nils_from_tuple(Data) when is_tuple(Data) ->
    TList = tuple_to_list(Data),
    Fun = fun(Element, Acc) ->
        case Element of
            nil -> Acc;
            Tuple when is_tuple(Tuple) -> Acc ++ [filter_out_nils_from_tuple(Tuple)];
            Other -> Acc ++ [Other]
        end
    end,
    Result = lists:foldl(Fun, [], TList),
    list_to_tuple(Result).
不过,此函数不会删除元组中的nils

您可以使用几个函数提取列表中的每个第一个非元组元素(如字符串“some”等):

函数
extract\u first\u非元组元素
是递归的,因为在您的示例中元组可以嵌套

因此,要测试这些功能:

Data1 = [{"some","other",[]}, nil, {{"more","somemore",[]}, nil, nil}].
filter_out_nils(Data1).
[{"some","other",[]},{{"more","somemore",[]},nil,nil}] % resulting list without nils
Data2 = extract_first_elements(Data1).
["some","more"] % extracted first elements
更新。 要从嵌套元组中删除nil,我们可以使用如下函数:

filter_out_nils(Data) when is_list(Data) ->
    Pred = fun(Element) -> Element /= nil end,
    lists:filter(Pred, Data). 
filter_out_nils_from_tuple(Data) when is_tuple(Data) ->
    TList = tuple_to_list(Data),
    Fun = fun(Element, Acc) ->
        case Element of
            nil -> Acc;
            Tuple when is_tuple(Tuple) -> Acc ++ [filter_out_nils_from_tuple(Tuple)];
            Other -> Acc ++ [Other]
        end
    end,
    Result = lists:foldl(Fun, [], TList),
    list_to_tuple(Result).

您可以使用如下函数从列表中删除NIL:

filter_out_nils(Data) when is_list(Data) ->
    Pred = fun(Element) -> Element /= nil end,
    lists:filter(Pred, Data). 
filter_out_nils_from_tuple(Data) when is_tuple(Data) ->
    TList = tuple_to_list(Data),
    Fun = fun(Element, Acc) ->
        case Element of
            nil -> Acc;
            Tuple when is_tuple(Tuple) -> Acc ++ [filter_out_nils_from_tuple(Tuple)];
            Other -> Acc ++ [Other]
        end
    end,
    Result = lists:foldl(Fun, [], TList),
    list_to_tuple(Result).
不过,此函数不会删除元组中的nils

您可以使用几个函数提取列表中的每个第一个非元组元素(如字符串“some”等):

函数
extract\u first\u非元组元素
是递归的,因为在您的示例中元组可以嵌套

因此,要测试这些功能:

Data1 = [{"some","other",[]}, nil, {{"more","somemore",[]}, nil, nil}].
filter_out_nils(Data1).
[{"some","other",[]},{{"more","somemore",[]},nil,nil}] % resulting list without nils
Data2 = extract_first_elements(Data1).
["some","more"] % extracted first elements
更新。 要从嵌套元组中删除nil,我们可以使用如下函数:

filter_out_nils(Data) when is_list(Data) ->
    Pred = fun(Element) -> Element /= nil end,
    lists:filter(Pred, Data). 
filter_out_nils_from_tuple(Data) when is_tuple(Data) ->
    TList = tuple_to_list(Data),
    Fun = fun(Element, Acc) ->
        case Element of
            nil -> Acc;
            Tuple when is_tuple(Tuple) -> Acc ++ [filter_out_nils_from_tuple(Tuple)];
            Other -> Acc ++ [Other]
        end
    end,
    Result = lists:foldl(Fun, [], TList),
    list_to_tuple(Result).

在示例中,过滤掉nil并获取嵌套元组的第一个元素可以通过单个递归函数来实现,其中
nil
案例中有一个子句

f([Item  | T], Acc) when is_tuple(Item) -> f([element(1, Item) | T], Acc);
f([nil   | T], Acc) -> f(T, Acc); % filter out nil
f([Other | T], Acc) -> f(T, [Other | Acc]);
f([], Acc) -> lists:reverse(Acc).
由于您添加了
erlangshell
标记,请注意此解决方案不会直接在shell中工作。实际上,shell中的递归函数应被编写为以函数(自身)为参数的函数(cf:)

还请注意,对于您的问题中未涉及的情况,此解决方案具有特定的行为:

  • 如果输入列表包含空元组,它将因函数子句错误而崩溃。然而,这可能是一种理想的行为。否则,您可以简单地添加一个新的function子句来根据需要处理它(空元组应该被过滤掉还是返回?)

  • 它将接受并返回列表中的非元组元素(nil除外),例如
    f([“some”,“more”],[])
    。为了避免这种情况,您需要稍微不同的逻辑

  • 如果参数不是正确的列表,它将崩溃


  • 在示例中,过滤掉nil并获取嵌套元组的第一个元素可以通过单个递归函数来实现,其中
    nil
    案例中有一个子句

    f([Item  | T], Acc) when is_tuple(Item) -> f([element(1, Item) | T], Acc);
    f([nil   | T], Acc) -> f(T, Acc); % filter out nil
    f([Other | T], Acc) -> f(T, [Other | Acc]);
    f([], Acc) -> lists:reverse(Acc).
    
    由于您添加了
    erlangshell
    标记,请注意此解决方案不会直接在shell中工作。实际上,shell中的递归函数应被编写为以函数(自身)为参数的函数(cf:)

    还请注意,对于您的问题中未涉及的情况,此解决方案具有特定的行为:

  • 如果输入列表包含空元组,它将因函数子句错误而崩溃。然而,这可能是一种理想的行为。否则,您可以简单地添加一个新的function子句来根据需要处理它(空元组应该被过滤掉还是返回?)

  • 它将接受并返回列表中的非元组元素(nil除外),例如
    f([“some”,“more”],[])
    。为了避免这种情况,您需要稍微不同的逻辑

  • 如果参数不是正确的列表,它将崩溃


  • 元组中有元组,它们的长度不同。这正常吗?元组中有元组,它们的长度不同。这正常吗?2>Data1=[{“一些”,“其他”,“其他”,“无”,无,{{“更多”,“一些”,“无”,无,无]。[{“some”,“other”,“[]},nil,{{“more”,“somemore”,“[]},nil,nil}]3>提取:过滤掉nils(数据1)。[{“some”,“other”,“[]},{{“more”,“somemore”,“[]},nil,nil}]它只过滤tuple@BranGi示例中的第二个和第三个零是元组的一部分。函数
    filter\u out\u nils
    只是从原始列表中删除“nil”原子。它不执行“深度移除”。尽管可以编写递归函数,从元组(和嵌套元组)中删除nils。@BranGi已经更新了
    filter\u out\u nils
    函数的逻辑。它现在从嵌套元组中删除nil:2>Data1=[{“some”,“other”,“[]},nil,{{“more”,“somemore”,“[]},nil,nil}]。[{“some”,“other”,“[]},nil,{{“more”,“somemore”,“[]},nil,nil}]3>提取:过滤掉nils(数据1)。[{“some”,“other”,“[]},{{“more”,“somemore”,“[]},nil,nil}]它只过滤tuple@BranGi示例中的第二个和第三个零是元组的一部分。函数
    filter\u out\u nils
    只是从原始列表中删除“nil”原子。它不执行“深度移除”。尽管可以编写递归函数,从元组(和嵌套元组)中删除nils。@BranGi已经更新了
    filter\u out\u nils
    函数的逻辑。它现在从嵌套元组中删除零: