Erlang:删除地图列表中的地图,然后 return 列表

Erlang: Delete a map in a list of maps, then return the list

我目前在我的程序的服务器端工作,我正在寻找一种方法,在我发现某个映射具有我正在搜索的原子后立即消除它。

下面的代码可以成功地找到带有 atom 的 map 是否存在于 maps 列表中,但我正在寻找一种方法来从列表中删除该 map 并且 return 整个列表没有我刚刚删除的地图。

"Asistente" 是我要找的原子。 L_Asistente 是地图本身的列表

第一种方法是当您覆盖了整个列表但未在映射列表中找到原子时。

第二个是搜索本身。目前,它在找到目标时会 return 为真,但我想将其更改为整个列表减去具有我正在搜索的原子的映射。

server_checaExistenciaBorrarAsistente(_, []) ->
    false;

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    [MapAsistente | Rest] = L_Asistentes,
    io:format("~p == ~p ~n", [MapAsistente, Asistente]),
    case maps:get("clave",MapAsistente) == Asistente of
        true ->
            true;
        false -> 
            server_checaExistenciaAsistente(Asistente, Rest)
    end. 

这里需要用到累加器:

server_checaExistenciaBorrarAsistente(_, [], Acc) ->
    Acc;

server_checaExistenciaBorrarAsistente(Asistente, [MapAsistente | Rest], Acc) ->
    io:format("~p == ~p ~n", [MapAsistente, Asistente]),
    case maps:find("clave", MapAsistente) of
        {ok, _} ->
            server_checaExistenciaBorrarAsistente(Asistente, Rest, Acc);
        error -> 
            server_checaExistenciaBorrarAsistente(Asistente, Rest, lists:append(Acc, [MapAsistente]))
    end. 

结果:

#{"abc" => 1,"clave" => a1} == #{"abc" => 1,"clave" => a1}
#{"abc" => 2,"clave1" => a2} == #{"abc" => 1,"clave" => a1}
#{"abc" => 3,"clave2" => a3} == #{"abc" => 1,"clave" => a1}
#{"abc" => 4,"clave3" => a4} == #{"abc" => 1,"clave" => a1}
[#{"abc" => 2,"clave1" => a2},
 #{"abc" => 3,"clave2" => a3},
 #{"abc" => 4,"clave3" => a4}]

你想这样做吗?

一种简单的方法是使用 list comprehension 来检查您要查找的密钥是否存在:

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    [MapAsistente || MapAsistente <- L_Asistentes,
         maps:find("clave", MapAsistente) =/= {ok, Asistente}].

一种更加模块化的方法是允许自定义过滤条件:

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    filter(L_Asistentes, fun(M) -> maps:find("clave", M) =/= {ok, Asistente} end).

filter(Maps, Filter) ->
    [Map || Map <- Maps, Filter(Map)].
server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    [MapAsistente || MapAsistente <- L_Asistentes,
         maps:find("clave", MapAsistente) =/= {ok, Asistente}].

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    filter(L_Asistentes, fun(M) -> maps:find("clave", M) =/= {ok, Asistente} end).

filter(Maps, Filter) ->
    [Map || Map <- Maps, Filter(Map)].

So let me get this straight. You use a "for" esque function to go throw the list and check each map, then you start comparing. Now the part I didn't understand is HOW you made it get filtered.

python 中,列表理解更具可读性:

results = [Map for Map in Maps if “clave” in Map]

而且,如果您愿意,可以将 if 条件提取到一个函数中:

def yes_or_no(Map):
    if 'clave’ in Map:
        return True
    else:
        return False

results = [Map for Map in Maps if yes_or_no(Map)]

请注意 yes_or_no() 接受一个参数,returns True 或 False。

这里有两个 erlang examples 你想知道的:

1)

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    [MapAsistente || MapAsistente <- L_Asistentes,
         maps:find("clave", MapAsistente) =/= {ok, Asistente}].

如果您进行这些替换:

|| ... for  
<- ... in
,  ... if

然后你会得到一个 python 列表理解:

[MapAsistente for MapAsistente in L_Asistentes if
         maps:find("clave", MapAsistente) =/= {ok, Asistente}].

所以你可以看到在 erlang 列表理解中,, 是一个 if-esque 结构。在本例中,maps:find() returns true/false 决定了Map是否会被包含在结果列表中,类似于python列表推导中的yes_or_no()

2)

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    filter(L_Asistentes, fun(M) -> maps:find("clave", M) =/= {ok, Asistente} end).

filter(Maps, Filter) ->
    [Map || Map <- Maps, Filter(Map)].

在这种情况下,不是使用列表理解来计算 server_checaExistenciaBorrarAsistente() 中的结果,而是将创建结果列表的所有工作都转移到一个辅助函数,该函数可以命名为 get_results():

server_checaExistenciaBorrarAsistente(Asistente, L_Asistentes) ->
    get_results(...).

get_results(Maps, Filter) ->
    [Map || Map <- Maps, Filter(Map)].

在 python 中,列表理解将如下所示:

[Map for Map in Maps if Filter(Map)]

辅助函数 get_results() 需要两个参数来构造结果:

  1. 地图列表。

  2. 一个函数,它接受一个参数和 returns true 或 false 来指示 Map 是否应该包含在结果列表中——就像 python yes_or_no()函数。

get_results() 中,您具有与第一种情况相同的列表理解结构:

[Map || Map <- Maps, Filter(Map)]

但这一次,true/false 由传递到辅助函数并存储在 Filter 变量中的函数确定。

如果有帮助,这是一个非常简单的例子:

func() ->
    my_helper(fun lists:reverse/1).

my_helper(SomeFunc) ->
    SomeFunc([1 , 2, 3]).

示例:

9> c(my).
{ok,my}
10> my:func().   
[3,2,1]