2015-11-27 56 views
-2

我在做Erlang,Haskell,Elixir和ES6的比較,我對Erlang和Elixir沒有太多的瞭解,但我想公平地表示所有這些語言,那麼這個Erlang代碼是否好呢?這是Erlang代碼的習慣嗎?

-module(mapreduce). 
-export([map_reduce/1]). 

add_to_key(KV, Sum) -> {Key, Value} = KV, 
         Tmp = proplists:get_value(Key, Sum, 0), 
         Newlist = proplists:delete(Key, Sum), 
         lists:append([{Key, Value + Tmp}], Newlist). 

map_reduce(Pl) -> lists:foldl(fun add_to_key/2, [], Pl). 

- 謝謝你們!

順便說一句,如果你們想看到的,這裏的哈斯克爾版本:

module MapReduce where 
import qualified Data.Map as M 

mapReduce :: [(String, Int)] -> [(String, Int)] 
mapReduce = foldl addToKey [] 
    where addToKey hl (k, v) = M.toList . M.insertWith (+) k v $ M.fromList hl 
+2

任何你想在erlang中使用列表的理由?爲什麼不是[dict](http://www.erlang.org/doc/man/dict.html)? 'update'似乎是最經濟的方法。 – rampion

+0

請不要要求對Stack Overflow進行代碼審查。 – Jubobs

+4

我投票結束這個問題作爲題外話題,因爲它是關於代碼審查。 – Jubobs

回答

1

我會寫這種方式(與版本> = 17的外殼測試),以限制數量列表創建/複製:

1> F = fun F([],L,_)-> L; F([{K,V}|T],[{K,V1}|T1],Func) -> F(T,[{K,Func(V,V1)}|T1],Func); F([{K,V}|T],L,Func) -> F(T,[{K,V}|L],Func) end. 
#Fun<erl_eval.42.54118792> 
2> MR = fun(L,Func) -> F(lists:sort(L),[],Func) end.                      
#Fun<erl_eval.12.54118792> 
3> MR([{1,2},{2,5},{1,6},{8,5},{2,1}],fun(A,B)-> A+B end).                    
[{8,5},{2,6},{1,8}] 
4> MR([{1,2},{2,5},{1,6},{8,5},{2,1}],fun(A,B)-> A*B end). 
[{8,5},{2,5},{1,12}] 
5> MR([{1,2},{2,5},{1,6},{8,5},{2,1}],fun(A,B)-> max(A,B) end). 
[{8,5},{2,5},{1,6}] 
10> 
+1

哇。那瘋狂的編碼就在那裏。 –

+0

我同意我沒有花很多時間來看看漂亮的代碼:o)。不過,我認爲如果輸入的proplist足夠大(需要一些基準來驗證它),它應該更具性能。 – Pascal

+0

非常酷,謝謝。 –

0

更地道的Erlang會使用模式的功能的語句頭add_to_key({Key, Value}, Sum)匹配但是當你在Haskell使用Data.Map你應該使用Erlang的類似的鍵/值存儲。在R17發佈之前,它主要是dict,但現在我們也有地圖。也有不常見的,使多餘的功能add_to_key/2(就個人而言,我更喜歡它,但它不是地道的。):

map_reduce(L) -> 
    F = fun({K, V}, M) -> 
      maps:put(K, V + maps:get(K, M, 0), M) 
     end, 
    maps:to_list(lists:foldl(F, #{}, L)). 

反正它不會是罕見的使用方法與排序列表中Pascalanswer

map_reduce(L) -> 
    F = fun({K, V1}, [{K, V2}|Acc]) -> 
      [{K, V1 + V2}|Acc]; 
      ({K, V}, Acc) -> 
      [{K, V}|Acc] 
     end, 
    lists:foldl(F, [], lists:sort(L)).