2017-01-09 18 views
2

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の標準ライブラリはどうすればこの問題を解決できますか?

答えて

2

あなたはすべてのErlangの項は匹敵し、タプルは辞書の順序を持​​つという事実を使うことができます。

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). 
+0

すごくエレガント! – Philip

+0

@Philip:エレガントですが、Dogbertのソリューションよりも効率が少し劣ります。 –

2

あり、正確にこれを行うための組み込み関数がありませんが、純粋な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 
関連する問題