Erlang是否相当于Ruby's min_by?
假设我有一个清单:
[
[{right, 1}, {up, 5}, {left, 4}], %element 1
[{up, 2}, {right, 3}, {down, 1}], %element 2
... % element N
]
一个将每个元素映射到标量的函数,例如:
f([{right, 1}, {up, 5}, {left, 4}]) -> 78.
f([{up, 2}, {right, 3}, {down, 1}]) -> 6.
现在我想找到映射到最小值的元素。在此示例中,我想查找[{up, 2}, {right, 3}, {down, 1}]
。
Erlang的标准库如何帮助我?
答案 0 :(得分:1)
没有内置函数可以做到这一点,但你可以为此编写一个简单的尾递归函数,它在纯Erlang中尽可能高效:
min_by([H|T], F) ->
min_by(T, F, H, F(H)).
min_by([H|T], F, MinValue, MinMapped) ->
case F(H) of
NewMapped when NewMapped < MinMapped ->
min_by(T, F, H, NewMapped);
_ ->
min_by(T, F, MinValue, MinMapped)
end;
min_by([], _, MinValue, _) -> MinValue.
1> c(a).
{ok,a}
2> a:min_by([1, 2, 3], fun (2) -> 0; (_) -> 1 end).
2
答案 1 :(得分:1)
你可以使用所有Erlang术语都具有可比性且tuple具有字典顺序的事实。
MinBy = fun(L, F) ->
{_, Min} = lists:min([{F(X), X} || X <- L]),
Min
end.
L = [
[{right, 1}, {up, 5}, {left, 4}] %element 1
, [{up, 2}, {right, 3}, {down, 1}] %element 2
].
F = fun([{right, 1}, {up, 5}, {left, 4}]) -> 78;
([{up, 2}, {right, 3}, {down, 1}]) -> 6
end.
MinBy(L, F).