在列表和列表列表上执行函数(Erlang)

时间:2014-12-03 13:18:36

标签: list foreach erlang list-comprehension nested-lists

我有两个清单:

Category_list = [a, b, c, d]
Id_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

对于Category_list中的每个元素以及Id_list中第一个列表中的每个元素,我想执行一个函数。想象一下,我有这个功能:

Check_id(Category, ID)

因此我需要一个像这样运行check_id的函数(但实际上有更多的ID):

Check_id(a, 1), Check_id(a, 2), Check_id(a, 3), Check_id(a, 4),
Check_id(b, 5), Check_id(b, 6), Check_id(b, 7), Check_id(b, 8),
Check_id(c, 9), Check_id(c, 10), Check_id(c, 11), Check_id(c, 12),
Check_id(d, 13), Check_id(d, 14), Check_id(d, 15), Check_id(d, 16).

Category_list中的元素数量和ID_list中的元素数量(列表)将始终相同。我尝试过使用列表推导以及"列表:foreach"一段时间现在无济于事。

4 个答案:

答案 0 :(得分:2)

我同意,你应该使用PascalCase,这是首字母大写的驼峰。不过,我不会为添加人工索引而烦恼。

-module(category).

-compile([export_all]).

run() ->
    Category_list = [a, b, c, d],
    Id_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]],
    Zipped = lists:zip(Category_list, Id_list),
    [check_categories(Category, List) || {Category, List} <- Zipped].

check_categories(Category, List) ->
    [check_category(Category, Element) || Element <- List].

check_category(Category, Element) ->
    io:format("~p ~p~n", [Category, Element]).

lists:zip/2获取两个列表并将它们合并到元组列表中:

[{a,[1,2,3,4]},{b,[5,6,7,8]},{c,"\t\n\v\f"},{d,[13,14,15,16]}]

然后,您可以使用{Category,ListOfElementsWithThisCategory}快速扫描元组。

答案 1 :(得分:1)

这是没有索引的O(n)解决方案

lists:foldl(
    fun (Category, [Ids | Id_listTail]) -> 
        lists:foreach(
            fun (Id) -> 
                Check_id(Category, Id) 
            end, Ids),
        Id_listTail
    end, Id_list, Category_list),

这个列表理解也适用于你:

%% note it's O(n^2) solution. Don't use it if Category list is much longer than in example:
[Check_id(lists:nth(N,Category_list), Id) || 
    N <-lists:seq(1,length(Category_list)), 
    Id <- lists:nth(N,Id_list)].

并且通常的做法是命名所谓的&#34;变量&#34;使用PascalCase

Check_id => CheckId
Category_list => CategoryList
Id_list => IdList

答案 2 :(得分:1)

check_id(C, Id) ->
    {C, Id}.

main()->
    Category_list = [a, b, c, d],
    Id_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]],

    Zip = lists:zip(Category_list, Id_list),
    Res = lists:map(fun({C, Ids}) -> [check_id(C, Id) || Id <- Ids] end, Zip),
    lists:flatten(Res).

你可以试试这个方法,输出是:

[{a,1},
 {a,2},
 {a,3},
 {a,4},
 {b,5},
 {b,6},
 {b,7},
 {b,8},
 {c,9},
 {c,10},
 {c,11},
 {c,12},
 {d,13},
 {d,14},
 {d,15},
 {d,16}]

答案 3 :(得分:0)

列表推导采用函数,类别列表和id子列表列表,并执行所有检查。它不会对列表和子列表大小产生任何约束(除非合理:o)。我添加了一个列表:flatten / 1来显示结果,但如果你不需要收集结果,它可能没用。

1> Check_id = fun(Cat,Id) -> {Cat,Id} end.
#Fun<erl_eval.12.90072148>
2> CatList = [a,b,c].
[a,b,c]
3> IdList = [[1,2,3],[4,5,6]].
[[1,2,3],[4,5,6]]
4> lists:flatten([[Check_id(Cat,Id) || Cat <- CatList, Id <- SubIdList] || SubIdList <- IdList]).
[{a,1},
 {a,2},
 {a,3},
 {b,1},
 {b,2},
 {b,3},
 {c,1},
 {c,2},
 {c,3},
 {a,4},
 {a,5},
 {a,6},
 {b,4},
 {b,5},
 {b,6},
 {c,4},
 {c,5},
 {c,6}]
5>