Erlang: вырваться из списков: foreach "loop" - PullRequest
5 голосов
/ 30 ноября 2009

У меня есть список элементов в Erlang, и я использую списки: foreach для перемещения по элементам в списке. Есть ли способ вырваться из этой «петли foreach» в середине обхода? Например: предположим, что я хочу прекратить обход списка дальше, если в списке встретится «1» [2, 4, 5, 1, 2, 5] Как мне это сделать?

Ответы [ 5 ]

8 голосов
/ 30 ноября 2009

Другой способ сделать это - использовать throw и catch:

catch lists:foreach(
        fun(1) ->
                throw(found_one);
           (X) ->
                io:format("~p~n", [X])
        end,
        [2, 4, 5, 1, 2, 5]).

При запуске в оболочке выводит:

2
4
5
found_one

EDIT : по многочисленным просьбам, более точная версия, которая улавливает только то, что вы хотите поймать:

try lists:foreach(
        fun(1) ->
                throw(found_one);
           (X) ->
                io:format("~p~n", [X])
        end,
        [2, 4, 5, 1, 2, 5])
catch
    throw:found_one ->
        found_one
end.
7 голосов
/ 30 ноября 2009
traverse(Liste) ->
 traverse(Liste, []).

traverse([], Acc) ->
 Acc;    

traverse([1|_], Acc) ->
 Acc;

traverse([H|T], Acc) ->
 % do something useful here maybe?
 traverse(T, Acc).

Конечно, это очень грубый пример.

3 голосов
/ 02 декабря 2009

В списках есть много приятных функций модуль:

lists:foreach(fun(E) -> do_something(E) end,
    lists:takewhile(fun(E) -> E =/= 1 end, List)).

или более эффективный, но менее приятный

lists:takewhile(fun(1) -> false;
                   (E) -> do_something(E), true
                end, List)
1 голос
/ 05 ноября 2015

списки: все

?
do_something(A) ->
   case A of 
      1 ->
         false;
      _ ->
         true
   end.

IsCompleted = lists:all(do_something(A), [2, 4, 5, 1, 2, 5]),

Срабатывает всякий раз, когда do_something возвращает false, и возвращает результаты в IsCompleted.

1 голос
/ 28 мая 2013

Я сталкиваюсь с той же проблемой и решаю ее следующим образом:

-module(foreach_until).
-export([foreach_until/3]).

foreach_until(Action, L, Judge)     ->
    lists:reverse(foreach_until(Action, L, Judge, []))
    .

foreach_until(_, [], _, Result) ->
    Result
    ;

foreach_until(Action, [H | T], Judge, Result)   ->
    case Judge(H) of 
        true    -> Result;
        false   -> foreach_until(Action, T, Judge, [Action(H) | Result])
    end
    .

Ниже приведен пример, объясняющий, как использовать:

60> foreach_until:foreach_until(fun(X) -> X*X end, [1,2,3,4], fun(X)-> X >= 3 end).
[1,4]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...