简体   繁体   English

从列表中删除钉子-Erlang

[英]Remove nils from a list - Erlang

How can I remove nils from this list ,lets say i get: 如何从此列表中删除nils,让我说:

[{"some","other",[]},nil,{{"more","somemore",[]},nil,nil}] [{“ some”,“ other”,[]},nil,{{“ more”,“ somemore”,[]},nil,nil]]

In the end I would like to extract only the first elements from the long tuples and put them on a list, Something like: 最后,我只想从长元组中提取第一个元素,并将它们放在列表中,例如:

["some", "more"] [“多一点”]

You can remove nils from the list using function like that: 您可以使用以下功能从列表中删除nil:

filter_out_nils(Data) when is_list(Data) ->
    Pred = fun(Element) -> Element /= nil end,
    lists:filter(Pred, Data). 

This function does not remove nils within tuples though. 但是,此函数不会删除元组中的nil。

And you can use a couple of functions to extract every first non tuple element in you list (like strings "some" and more): 您可以使用几个函数来提取列表中的每个第一个非元组元素(例如字符串“ some”等):

extract_first_elements(Data) when is_list(Data) ->
    lists:map(fun extract_first_non_tuple_element/1, Data).

extract_first_non_tuple_element({})-> {};
extract_first_non_tuple_element(Data) when is_tuple(Data)-> 
    case element(1, Data) of
        First when is_tuple(First) -> extract_first_non_tuple_element(First);
        Other -> Other
    end.

Function extract_first_non_tuple_element is recursive, because in your example tuple can be nested. 函数extract_first_non_tuple_element是递归的,因为在您的示例中,元组可以嵌套。

So to test this functions: 因此,要测试此功能:

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

Update. 更新。 To remove nils from nested tuples we can use function like that: 要从嵌套元组中删除nil,我们可以使用如下函数:

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).

Filtering out nils and getting the first element of nested tuples in your example can be achieved with a single recursive function, with a clause for the nil case : 可以使用单个递归函数(使用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).

Since you added erlang-shell tag, please note this solution will not work directly in the shell. 由于您添加了erlang-shell标记,因此请注意,该解决方案无法直接在shell中使用。 Indeed, recursive functions in the shell shall be written as functions taking a function (themselves) as an argument (cf: How do you write a fun that's recursive in Erlang? ). 实际上,外壳程序中的递归函数应编写为以一个函数(自身)作为参数的函数(参见: 如何编写在Erlang中递归的乐趣? )。

F = fun(F, [Item  | T], Acc) when is_tuple(Item) ->
            F(F, [element(1, Item) | T], Acc);
       (F, [nil   | T], Acc) -> F(F, T, Acc);
       (F, [Other | T], Acc) -> F(F, T, [Other | Acc]);
       (_F, [], Acc) -> lists:reverse(Acc)
    end.
F(F, List, []).

Please also note that this solution has specific behaviors for cases not covered in your question: 另请注意,对于您的问题未涵盖的案例,此解决方案具有特定的行为:

  1. It will crash with a function clause error if the input list contains an empty tuple. 如果输入列表包含一个空的元组,它将崩溃并出现一个函数子句错误。 Yet, this might be a desired behavior. 但是,这可能是理想的行为。 Otherwise, you can simply add a new function clause to handle it as desired (should empty tuples be filtered out or returned?). 否则,您可以简单地添加一个新的函数子句以根据需要对其进行处理(应该将空元组过滤掉还是返回?)。

  2. It will accept and return non-tuple elements in the list (except nil), eg f(["some", "more"], []) . 它将接受并返回列表中的非元组元素(nil除外),例如f(["some", "more"], []) To avoid this, you would need a slightly different logic. 为了避免这种情况,您将需要一个稍微不同的逻辑。

  3. It will crash if the argument is not a proper list. 如果参数不是正确的列表,它将崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM