> Erlang中文手册 > fold/3 调用函数对字典里的键值进行递归遍历操作

dict:fold/3

调用函数对字典里的键值进行递归遍历操作

用法:

fold(Fun, Acc0, Dict) -> Acc1

内部实现:

-spec fold(Fun, Acc0, Dict) -> Acc1 when
      Fun :: fun((Key, Value, AccIn) -> AccOut),
      Dict :: dict(Key, Value),
      Acc0 :: Acc,
      Acc1 :: Acc,
      AccIn :: Acc,
      AccOut :: Acc.

%%  Fold function Fun over all "bags" in Table and return Accumulator.

fold(F, Acc, D) -> fold_dict(F, Acc, D).

fold_dict(F, Acc, D) ->
    Segs = D#dict.segs,
    fold_segs(F, Acc, Segs, tuple_size(Segs)).

fold_segs(F, Acc, Segs, I) when I >= 1 ->
    Seg = element(I, Segs),
    fold_segs(F, fold_seg(F, Acc, Seg, tuple_size(Seg)), Segs, I-1);
fold_segs(F, Acc, _, 0) when is_function(F, 3) -> Acc.

fold_seg(F, Acc, Seg, I) when I >= 1 ->
    fold_seg(F, fold_bucket(F, Acc, element(I, Seg)), Seg, I-1);
fold_seg(F, Acc, _, 0) when is_function(F, 3) -> Acc.

fold_bucket(F, Acc, [?kv(Key,Val)|Bkt]) ->
    fold_bucket(F, F(Key, Val, Acc), Bkt);
fold_bucket(F, Acc, []) when is_function(F, 3) -> Acc.

字典里的每一对键值跟一个临时累积参数(Acc0)一起被函数(Fun)调用,并返回一个新的累积器(Accumulator)以传给下一次函数调用,直到字典里所有的键值对都被函数(Fun)遍历调用完,最后返回一个累积结果值 Acc1。例如下面求字典里所有值的平方和:

D = dict:from_list([{k1, 1}, {k2, 2}, {k3, 3}]),
dict:fold(fun(_Key, Val, Acc) -> Val * Val + Acc end, 0, D).