Search code examples
functional-programmingerlangejabberderlang-otperlang-shell

Remove nils from a list - Erlang


How can I remove nils from this list ,lets say i get:

[{"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"]


Solution

  • You can remove nils from the list using function like that:

    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.

    And you can use a couple of functions to extract every first non tuple element in you list (like strings "some" and more):

    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.

    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:

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