如何检查列表理解中每个元素的响应

时间:2012-05-20 11:44:54

标签: erlang

在以下代码中,我想检查start_item的每次调用的结果是否为ok。 在ok=之前添加start_item是不可能的。

start_item_group(Community_code,Category_code,Group_code)->
    [
     start_item(Community_code,Category_code,Item_seq_no)
     ||
     {_Community_code,_Category_code,Item_seq_no} 
     <-
     dis_scan:get_group_item(Community_code,Category_code,Group_code),    
    ok.

4 个答案:

答案 0 :(得分:2)

实际上,通过将模式匹配作为过滤器移动到列表推导中,可以检查哪些start_item调用不返回ok!就个人而言,我会这样做:

start_item_group(Community_code,Category_code,Group_code)->
  Failed = [
    Item ||
    {_Comm_code, _Cat_code, Item} <- dis_scan:get_group_item(Community_code,Category_code,Group_code),
    ok =/= start_item(Community_code, Category_code, Item)
  ],
  do_stuff_with(Failed).

答案 1 :(得分:1)

使用可以使用列表:foreach。 foreach将函数作为参数,您可以在这些函数中编写所需的全部内容。

答案 2 :(得分:1)

你可以有一个包装器函数来调用并检查start_item的函数评估结果,如果不是'ok'(或'ok'),还可以做任何需要做的事情:

start_item_check(ok) ->
  %% return/do whatever needs to be done if response is ok;
start_item_check(not_ok) ->
  %% return/do whatever needs to be done if response is not ok;
start_item_check(StartItemResponse) ->
  %% do whatever needs to be done if not 'ok' nor 'not_ok';
  %% it's up to your business logic.

start_item_group(Community_code,Category_code,Group_code) ->
  [
    start_item_check(start_item(Community_code,Category_code,Item_seq_no))
    ||
    {_Community_code,_Category_code,Item_seq_no}
    <-
    dis_scan:get_group_item(Community_code,Category_code,Group_code)
  ].

如果要根据'start_item'函数返回的内容过滤掉元素,可以使用list:filter在您使用实现生成的列表中。 如果你希望继续使用列表理解,那就是你可以做的;否则你可以使用列表:foreach as W55tKQbuRu28Q4xv prev。建议。

答案 3 :(得分:1)

我以前做过类似的事情,但是以不同的方式。我也需要检查表达式的结果。我的诀窍的好处是你不需要自己检查,模式匹配为你做。这个技巧的关键是使用list:foldl。下面是一个例子。

check_group(Community_code,Category_code,Group_code) ->
    Group = dis_scan:get_group_item(Community_code,Category_code,Group_code),
    StartItems = [ start_item(Community_code,Category_code,Item_seq_no) 
               || {_, _, Item_seq_no } <- Group ],
    ok = lists:foldl(fun check_start_item/2, ok, StartItems),
    exit(normal).

check_start_item(StartItem, ok) -> 
    ## Return ok if item is ok, {error, Reason} otherwise.
    ok.

另一方面,如果您需要按照检查返回的结果对项目进行分组,请使用lists:partition。

check_group(Community_code,Category_code,Group_code) ->
    Group = dis_scan:get_group_item(Community_code,Category_code,Group_code),
    StartItems = [ start_item(Community_code,Category_code,Item_seq_no) 
               || {_, _, Item_seq_no } <- Group ],
    {GoodItems, BadItems} = lists:partition(fun check_start_item/1, StartItems),
    case BadItems of 
        [] -> exit(normal);
         _ -> error({bad_start_items, BadItems})
    end.

check_start_item(StartItem) -> 
    ## Return true if item is ok, false otherwise.
    true.