簡體   English   中英

從列表中刪除釘子-Erlang

[英]Remove nils from a list - Erlang

如何從此列表中刪除nils,讓我說:

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

最后,我只想從長元組中提取第一個元素,並將它們放在列表中,例如:

[“多一點”]

您可以使用以下功能從列表中刪除nil:

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

但是,此函數不會刪除元組中的nil。

您可以使用幾個函數來提取列表中的每個第一個非元組元素(例如字符串“ 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.

函數extract_first_non_tuple_element是遞歸的,因為在您的示例中,元組可以嵌套。

因此,要測試此功能:

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

由於您添加了erlang-shell標記,因此請注意,該解決方案無法直接在shell中使用。 實際上,外殼程序中的遞歸函數應編寫為以一個函數(自身)作為參數的函數(參見: 如何編寫在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, []).

另請注意,對於您的問題未涵蓋的案例,此解決方案具有特定的行為:

  1. 如果輸入列表包含一個空的元組,它將崩潰並出現一個函數子句錯誤。 但是,這可能是理想的行為。 否則,您可以簡單地添加一個新的函數子句以根據需要對其進行處理(應該將空元組過濾掉還是返回?)。

  2. 它將接受並返回列表中的非元組元素(nil除外),例如f(["some", "more"], []) 為了避免這種情況,您將需要一個稍微不同的邏輯。

  3. 如果參數不是正確的列表,它將崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM