进入深层嵌套的地图和列表

时间:2018-07-30 14:35:55

标签: elixir

我有一张看起来像这样的地图:

%{
  "conferences" => [
    %{
      "alias" => "EASTERN",
      "divisions" => [
        %{
          "alias" => "SOUTHEAST",
          "id" => "54dc7348-c1d2-40d8-88b3-c4c0138e085d",
          "name" => "Southeast",
          "teams" => [
            %{
              "alias" => "WAS",
              "id" => "583ec8d4-fb46-11e1-82cb-f4ce4684ea4c",
              "market" => "Washington",
              "name" => "Wizards",
              "reference" => "1610612764",
              "sr_id" => "sr:team:3431",
              "venue" => %{
                "address" => "601 F St. N.W.",
                "capacity" => 20356,
                "city" => "Washington",
                "country" => "USA",
                "id" => "f62d5b49-d646-56e9-ba60-a875a00830f8",
                "name" => "Capital One Arena",
                "state" => "DC",
                "zip" => "20004"
              }
            }
          ]
        },
      ],
      "id" => "3960cfac-7361-4b30-bc25-8d393de6f62f",
      "name" => "EASTERN CONFERENCE"
    },
    %{
      "alias" => "WESTERN",
      "divisions" => [
        %{
          "alias" => "NORTHWEST",
          "id" => "12bf14ba-eb16-4c6f-8275-e801b6947c1e",
          "name" => "Northwest",
          "teams" => [
            %{
              "alias" => "DEN",
              "id" => "583ed102-fb46-11e1-82cb-f4ce4684ea4c",
              "market" => "Denver",
              "name" => "Nuggets",
              "reference" => "1610612743",
              "sr_id" => "sr:team:3417",
              "venue" => %{
                "address" => "1000 Chopper Circle",
                "capacity" => 19155,
                "city" => "Denver",
                "country" => "USA",
                "id" => "1a28ef88-76c9-5bcc-b4ee-51d30ca98f4f",
                "name" => "Pepsi Center",
                "sr_id" => "sr:venue:5976",
                "state" => "CO",
                "zip" => "80204"
              }
            }
          ]
        }
      ],
      "id" => "7fe7e212-de01-4f8f-a31d-b9f0a95731e3",
      "name" => "WESTERN CONFERENCE"
    }
  ],
  "league" => %{
    "alias" => "NBA",
    "id" => "4353138d-4c22-4396-95d8-5f587d2df25c",
    "name" => "NBA"
  }
}

如何仅拔出team ids?这样我得到的列表看起来像这样=> ["583ec8d4-fb46-11e1-82cb-f4ce4684ea4c", "583ed102-fb46-11e1-82cb-f4ce4684ea4c"]

当前尝试:

如果Data代表上面的地图。

conferences = get_in(data, ["conferences"])
divisions = Enum.map(conferences, fn(c) -> c["divisions"] end)
Enum.map(divisions, fn(d) -> d["teams"] end)

错误消息:

** (ArgumentError) the Access calls for keywords expect the key to be an atom, got: "teams"

2 个答案:

答案 0 :(得分:3)

虽然@Dogbert的回答通常是很好并且很有效,但为了将来的访问者,我会发布另一种方法(在这种特殊情况下,它比方法更冗长,一般来说更糟)一种使用理解力。)

此人正在使用Access

data
|> get_in([
     Access.key("conferences"),
     Access.all(),
     Access.key("divisions"),
     Access.all(),
     Access.key("teams"),
     Access.all(),
     Access.key("id")
   ])
|> List.flatten
#⇒ ["583ec8d4-fb46-11e1-82cb-f4ce4684ea4c",
#   "583ed102-fb46-11e1-82cb-f4ce4684ea4c"]

答案 1 :(得分:2)

问题在于c["divisions"]本身是一个列表,因此您最终在divisions中得到一个列表列表,这会使最后一个Enum.map失败,因为您尝试访问列表中的["teams"]。如果要处理所有会议中的所有部门,只需将第二行从Enum.map更改为Enum.flat_map

divisions = Enum.flat_map(conferences, fn(c) -> c["divisions"] end)

此外,我会像这样用for编写整个内容:

ids =
  for conference <- data["conferences"],
      division <- conference["divisions"],
      team <- division["teams"],
      do: team["id"]

IO.inspect ids

输出:

["583ec8d4-fb46-11e1-82cb-f4ce4684ea4c", "583ed102-fb46-11e1-82cb-f4ce4684ea4c"]