【问题标题】:Left outer join with Elixir's for comprehension左外连接与 Elixir 的理解
【发布时间】:2015-10-19 01:13:09
【问题描述】:

我一直在研究我可以用EnumStreamfor 理解做些什么,我正在努力重现左外连接行为。我可以使用Enum.reduce 实现左外连接函数,但如果有某种方法可以使用for 来实现,我宁愿使用它。

我知道 python 支持它,我见过它herehere,我想 Elixir 的理解是受到 python 的启发。我们可以在 Elixir 中做到吗?

假设我有两个来自外部 API 或某个 json/xml 文件的列表:

categories = [%{id: 1, name: "beverages"}, %{id: 2, name: "vegetables"}]
products = [%{name: "ice tea", category: 1}, %{name: "sake", category: 1}]

我想离开外部加入他们以获得类似的东西:

cat_product == [
  %{category: "beverages", product: "ice tea"},
  %{category: "beverages", product: "sake"},
  %{category: "vegetables", product: "(No product)"}
]

还有类似的:

cat_products == [
  %{name: "beverages", products: [list of products]}
  %{name: "vegetables", products: []}
]

【问题讨论】:

    标签: elixir


    【解决方案1】:

    您的第一个示例不能在外部使用 for 循环优雅地编写,因为左侧列表中的记录可能与右侧列表中的多个记录相连。然而,for 理解将最多为原始集合中的每个元素产生一个结果。在这种情况下,使用Enum.flat_map会更合适:

    Enum.flat_map categories, fn(c) ->
      case Enum.filter(products, fn(p) -> p.category == c.id end) do
        [] ->
          [%{name: c.name, product: nil}]
        prods ->
          for p <- prods, do: %{name: c.name, product: p.name}
      end
    end
    

    您的第二个示例只需使用for 推导即可轻松实现,因为原始集合中的每个元素在结果集中始终只有一个元素。过滤不是使用Enum.filter,而是使用内部for 理解的第二个参数完成的,这使得代码更加清晰。

    for c <- categories do
      prod = for p <- products, p.category == c.id do
        p.name
      end
      %{name: c.name, products: prod}
    end
    

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多