gpt4 book ai didi

elixir - 如何同时映射和group_by?

转载 作者:行者123 更新时间:2023-12-04 10:15:57 25 4
gpt4 key购买 nike

举例来说,假设我有一对collection的可枚举{first, second}。使用以下分组对

Enum.group_by(collection, fn {first, second} -> first end)

将产生一个 Map,其键由传递的匿名函数确定。它的值是对的集合。
但是,我希望它的值改为包含该对的 second元素。

通常,给定一个可枚举的对象,我想分组提供 key 提取器和值映射器,以便我可以确定将哪些内容放入结果 Map的值中。即,我想要类似的东西
map_group_by(
collection,
fn {_first, second} -> second end,
fn {first, _second} -> first end
)

其中 collection的值在分组之前已被映射,而键映射器仍在原始元素上运行。

标准库中有这样的功能吗?如果没有,实现这一目标的最惯用的方法是什么?

我知道我可以做类似的事情
Enum.reduce(
collection,
%{},
fn({key, value}, acc) -> Dict.update(acc, key, [value], &([value | &1])) end
)

但这似乎很笨拙,并且会抢先创建 [value]列表(实际上是这样吗?)。有没有一种既简洁又有效的更好的方法?

最佳答案

真实答案

从Elixir 1.3开始,现在有Enum.group_by/3的第三个参数是一个映射到键上的函数。

过时的答案

但我给你我的解决方案:

首先,请务必注意,就像在Elixir Docs中看到的那样,元组列表与键值列表相同:

iex> list = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> list == [a: 1, b: 2]
true

因此,考虑到这一点,很容易在其上使用 Enum.map

这确实使它通过了两次,但是看起来比您拥有的要干净一些:
defmodule EnumHelpers do
def map_col(lst) do
lst
|> Enum.group_by(fn {x, _} -> x end)
|> Enum.map(fn {x, y} -> {x, Dict.values y} end)
end
end

IO.inspect EnumHelpers.map_col([a: 2, a: 3, b: 3])

它将打印出:
[a: [3, 2], b: [3]]

编辑: 更快的版本:
defmodule EnumHelpers do

defp group_one({key, val}, categories) do
Dict.update(categories, key, [val], &[val|&1])
end

def map_col_fast(coll) do
Enum.reduce(coll, %{}, &group_one/2)
end
end

IO.inspect EnumHelpers.map_col_fast([a: 2, a: 3, b: 3])

关于elixir - 如何同时映射和group_by?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35417028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com