我怎样才能从这个列表中删除 nils,假设我得到:
[{"some","other",[]},nil,{{"more","somemore",[]},nil,nil}]
最后,我只想从长元组中提取第一个元素并将它们放在一个列表中,例如:
[“多一点”]
我怎样才能从这个列表中删除 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 并获取嵌套元组的第一个元素可以通过一个递归函数来实现,并带有一个case子句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 中工作。实际上,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, []).
另请注意,对于您的问题未涵盖的情况,此解决方案具有特定行为:
如果输入列表包含空元组,它将因函数子句错误而崩溃。然而,这可能是一种期望的行为。否则,您可以简单地添加一个新的函数子句来根据需要处理它(是否应该过滤掉或返回空元组?)。
它将接受并返回列表中的非元组元素(nil 除外),例如f(["some", "more"], [])
. 为避免这种情况,您需要稍微不同的逻辑。
如果参数不是正确的列表,它将崩溃。