基于另一个嵌套的 Map 迭代更新 Map

意大利辣香肠比萨

Elixir 中的不变性真的让我大吃一惊,使语言使用起来如此混乱。我需要迭代嵌套地图并根据迭代简单更新一些计数,但这Enum.reduce对我来说很困难。说我有:

defmodule Predictor do

  def past_matches() do
    [
      team1: %{team2: %{f: 0, a: 1},  team3: %{f: 1, a: 3}},
      team2: %{team1: %{f: 3, a: 0},  team3: %{f: 2, a: 0}},                    
      team3: %{team1: %{f: 1, a: 0},  team2: %{f: 0, a: 1}},
    ]
  end


  def init_indexes(matches) do
    local = Enum.reduce matches, %{}, fn({team, _scores}, acc) ->
      Map.put acc, team, %{f: 0, a: 0, n_games: 0}
    end

    Enum.each matches, fn({team, scores}) ->
      Enum.each scores, fn({vteam, %{f: ff, a: aa}}) ->
        %{f: fi, a: ai, n_games: ni} = local[team]
        put_in(local[team], %{f: fi+ff, a: ai+aa, n_games: ni+1})
      end
    end

    local
  end

  def run() do
    local = past_matches() |> init_indexes()
  end
end

我只需要local总结f,an_games

local = %{
    team1: %{f: 1, a: 4, n_games: 2}
    ...
}

在年底run()明显的地图local有全0和没有更新的价值。

凯特·赫奇佩斯

有几件事我可以立即看到让你绊倒:

  • Enum.each/2将对列表中的每个项目应用一个函数,但它不会以任何方式累积结果或修改原始列表。我不记得上次使用是Enum.each什么时候了——它有它的位置,但非常罕见。

  • 这意味着您调用的地方local[team]实际上并没有更新任何值,因为该输出没有传递到其他任何地方。它本质上只是将这些更改发送到以太坊中。

  • 解决方案:管道!我向你保证,|>管道操作员会改变你的生活。如果您来自面向对象的背景,一开始有点令人难以置信,但坚持下去,我保证您永远不想回去。帮助我理解它的思维转变是一开始尽可能少地使用匿名函数。它帮助我适应了不变性的概念,因为它迫使我思考每个函数实际需要什么值,以及如何将这些值传递给每个函数。

这是我尝试使用更以管道为中心的方法重写您的模块 - 希望它有所帮助。当您在 IEx 中运行它时,它会产生预期的结果。如果您有任何疑问,我很乐意澄清任何问题。

defmodule Predictor do

  @past_matches [
    team1: %{
      team2: %{f: 0, a: 1},
      team3: %{f: 1, a: 3}
    },
    team2: %{
      team1: %{f: 3, a: 0},
      team3: %{f: 2, a: 0}
    },
    team3: %{
      team1: %{f: 1, a: 0},
      team2: %{f: 0, a: 1}
    }
  ]

  # see note 1    
  @baseline %{f: 0, a: 0, n_games: 0}

  def run(past_matches \\ @past_matches) do
    past_matches
    |> Enum.map(&build_histories/1)
    |> Enum.into(%{}) 
    # see note 2
  end

  def build_histories({team, scores}) do
    history = Enum.reduce(scores, @baseline, &build_history/2)
    {team, history}
  end

  def build_history({_vteam, vresults}, acc) do
    # see note 3
    %{acc | f: acc.f + vresults.f,
            a: acc.a + vresults.a,
            n_games: acc.n_games + 1}
  end
end

(1) since the baseline is the same for every team, you can 
    set it as a module attribute -- basically like setting a global 
    (immutable) variable that you can use as a starting point for a new 
    value. Another option would be to create a %BaseLine{} struct that 
    has default values.

(2) you could also use `Enum.reduce/2` here instead, but this does 
    effectively the same thing -- the output of the `Enum.map/1` 
    call is a list of {atom, _val} which is interpreted as a Keyword 
    list; calling `Enum.into(%{}) turns a Keyword list into a map 
    (and vice versa with `Enum.into([])`).

(3) NB:  %{map | updated_key: updated_val} only works on maps or 
    structs where the key to be updated already exists -- it'll throw 
    an error if the key isn't found on the original map.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何遍历另一个 Map 内的 Map?

来自分类Dev

Mockito,JUnit和Map嵌套在另一个类中

来自分类Dev

确定一个 Map 是否是另一个 Map 的子集

来自分类Dev

Golang Map结构在另一个

来自分类Dev

使用另一个类的 Map Fragment

来自分类Dev

forEach和map函数迭代对象的嵌套json数组并创建一个新数组

来自分类Dev

在freemarker中迭代Map of Map的Map

来自分类Dev

我可以将std :: map的内容分配到另一个std :: map吗?

来自分类Dev

C ++:使用map作为另一个map的值

来自分类Dev

检查map <string,string>是否包含另一个map <string,string>

来自分类Dev

如何从另一个Map对象Java中提取Map对象

来自分类Dev

将 Scala Map 添加到另一个 Scala Map

来自分类Dev

将对象从一个unordered_map移到另一个容器

来自分类Dev

将一个Map值存储到另一个

来自分类Dev

在Scala中,如何检查一个Map是否包含另一个Map的所有条目?

来自分类Dev

通过更新F#Map与C#字典进行迭代

来自分类Dev

通过更新F#Map与C#字典进行迭代

来自分类Dev

JavaScript .map()用另一个数组中的值更新数组-返回值,但键未定义

来自分类Dev

Map Java的递归迭代

来自分类Dev

.map()迭代对象数组

来自分类Dev

如何迭代 Map() 对象?

来自分类Dev

Map.prototype.forEach 不迭代 Map

来自分类Dev

基于另一个对值进行计数,并通过嵌套表进行迭代-LUA

来自分类Dev

如何更新Map类型的嵌套对象

来自分类Dev

Scala 将 Map 和 groupby 映射到另一个 Map,使用较小的键集

来自分类Dev

Android-Google Map将摄像头从位置移动到另一个

来自分类Dev

从另一个线程插入/擦除时,能否访问C ++ 11 std :: map条目?

来自分类Dev

单击google map infowindow时调用另一个片段页面

来自分类Dev

Scala Spark-引用另一个数据框的Map函数

Related 相关文章

  1. 1

    如何遍历另一个 Map 内的 Map?

  2. 2

    Mockito,JUnit和Map嵌套在另一个类中

  3. 3

    确定一个 Map 是否是另一个 Map 的子集

  4. 4

    Golang Map结构在另一个

  5. 5

    使用另一个类的 Map Fragment

  6. 6

    forEach和map函数迭代对象的嵌套json数组并创建一个新数组

  7. 7

    在freemarker中迭代Map of Map的Map

  8. 8

    我可以将std :: map的内容分配到另一个std :: map吗?

  9. 9

    C ++:使用map作为另一个map的值

  10. 10

    检查map <string,string>是否包含另一个map <string,string>

  11. 11

    如何从另一个Map对象Java中提取Map对象

  12. 12

    将 Scala Map 添加到另一个 Scala Map

  13. 13

    将对象从一个unordered_map移到另一个容器

  14. 14

    将一个Map值存储到另一个

  15. 15

    在Scala中,如何检查一个Map是否包含另一个Map的所有条目?

  16. 16

    通过更新F#Map与C#字典进行迭代

  17. 17

    通过更新F#Map与C#字典进行迭代

  18. 18

    JavaScript .map()用另一个数组中的值更新数组-返回值,但键未定义

  19. 19

    Map Java的递归迭代

  20. 20

    .map()迭代对象数组

  21. 21

    如何迭代 Map() 对象?

  22. 22

    Map.prototype.forEach 不迭代 Map

  23. 23

    基于另一个对值进行计数,并通过嵌套表进行迭代-LUA

  24. 24

    如何更新Map类型的嵌套对象

  25. 25

    Scala 将 Map 和 groupby 映射到另一个 Map,使用较小的键集

  26. 26

    Android-Google Map将摄像头从位置移动到另一个

  27. 27

    从另一个线程插入/擦除时,能否访问C ++ 11 std :: map条目?

  28. 28

    单击google map infowindow时调用另一个片段页面

  29. 29

    Scala Spark-引用另一个数据框的Map函数

热门标签

归档