我想在Erlang编程语言中对列表进行搜索。
由于Erlang没有循环结构,我们使用递归方法来实现循环。
然而,我想知道如何打破这个循环?
比如说,一旦我们在列表中找到了所需的元素。
就像在C语言中使用break
一样。
Elem = 3
List = [1,2,3,4,5,6]
elem_in_list(_Elem, []) -> false;
elem_in_list(Elem, [Elem | _Rest]) -> true;
elem_in_list(Elem, [_Head | Rest]) -> elem_in_list(Elem, Rest).
List
中查找 3
。如果我们展开这个过程,它看起来会像这样。elem_in_list(3, [ 1 | [2,3,4,5,6]]) % Matches [_Head | Rest]
elem_in_list(3, [ 2 | [3,4,5,6]]) % Matches [_Head | Rest]
elem_in_list(3, [ 3 | [4,5,6]]) % Matches [Elem | _Rest]
true
Justin的答案是正确的。你只需要在那时停止递归。 但有时你不是自己编写递归,而是想要从内部函数(比如fold中的函数)中退出。这就是为什么Erlang有一个非局部返回关键字(即:throw)。 让我给你展示:
假设你想使用高阶函数在列表中找到最小的正整数。你可以编写以下函数:
min_pos_int(List) ->
lists:foldl(
fun (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List).
1
)。因此,如果你的列表中有1
作为元素,你可以在那里停止,对吧?
好的。在 Erlang 中,你可以通过 catch
和 throw
实现这一点,就像这样...min_pos_int(List) ->
catch lists:foldl(
fun (1, _) -> throw(1)
; (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List).
您也可以使用try...catch...
语法来实现此功能。
min_pos_int(List) ->
try lists:foldl(
fun (1, _) -> throw(1)
; (Int, Min) when is_integer(Int), Int > 0, Int < Min -> Int
; (_, Min) -> Min
end, infinity, List)
catch EarlyResult -> EarlyResult
end.
您可以通过执行以下操作来检查它是否有效...
1> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % with catch & throw
{1,1}
2> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % without them
{2837520,1}
3> c(my_mod), timer:tc(my_mod, min_pos_int, [L]). % with try...catch
{7,1}
您可以通过几种方法实现搜索,但如果您需要在列表中查找第一个匹配项,可以尝试使用带有以下条件的列表生成器:
1> [X || X <- [1, 2, 3, 4, 5], X =:= 3].
[3]
所以,我想你可以尝试在一些case
块中使用它,例如:
case [X || X <- [1, 2, 3, 4, 5], X =:= 3] of
[_] -> find;
[] -> not_found
end.