Recursion Elixir map_减少引用最后一个元素
在与列表中的最后一个元素进行比较时,如何循环(递归地或使用Recursion Elixir map_减少引用最后一个元素,recursion,elixir,Recursion,Elixir,在与列表中的最后一个元素进行比较时,如何循环(递归地或使用reduce)一个映射的列表 例如,假设我有一个这样的地图列表: datetime = Timex.beginning_of_day(Timex.now) data = [%{a: 0, cluster: 0, time: datetime}, %{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)}, %{a:
reduce
)一个映射的列表
例如,假设我有一个这样的地图列表:
datetime = Timex.beginning_of_day(Timex.now)
data = [%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 0, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 0, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 0, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 2, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 2, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 2, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 1, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 1, time: Timex.shift(datetime, minutes: 38)}]
[%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 2, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 2, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 2, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 3, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 3, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 3, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 4, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 4, time: Timex.shift(datetime, minutes: 38)}]
我想修改每个映射的cluster
属性,以表示它所处的组(相对于它所处的顺序)
如果集群
ID没有重复,那么使用groupby
是很好的选择
我想在他们更改组时对他们进行分组,结果如下:
datetime = Timex.beginning_of_day(Timex.now)
data = [%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 0, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 0, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 0, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 2, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 2, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 2, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 1, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 1, time: Timex.shift(datetime, minutes: 38)}]
[%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 2, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 2, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 2, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 3, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 3, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 3, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 4, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 4, time: Timex.shift(datetime, minutes: 38)}]
为此,我需要将列表中的当前项与前一项进行比较。我从下面这样的内容开始,然后停止,因为我知道它不会引用上一个项目来比较当前项目和上一个项目:
Enum.map_reduce(data, 0, fn(x, acc) -> cluster_grouping(x, acc) end)
def cluster_grouping(x, acc) do
cond do
x.cluster == acc -> {Map.put(x, :cluster, acc), acc}
x.cluster > acc -> {Map.put(x, :cluster, acc), acc + 1}
end
end
您需要在累加器中保留两个整数:当前生成的集群(每次更改都会增加1)和集群的最后一个原始值
datetime = Timex.beginning_of_day(Timex.now)
data = [%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 0, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 0, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 0, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 2, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 2, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 2, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 1, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 1, time: Timex.shift(datetime, minutes: 38)}]
Enum.map_reduce(data, {0, 0}, fn x, {i, last} ->
i = if x.cluster == last, do: i, else: i + 1
{Map.put(x, :cluster, i), {i, x.cluster}}
end)
|> elem(0)
|> IO.inspect
输出:
[
%{a: 0, cluster: 0, time: #DateTime<2018-02-18 00:00:00Z>},
%{a: 1, cluster: 0, time: #DateTime<2018-02-18 00:03:00Z>},
%{a: 2, cluster: 0, time: #DateTime<2018-02-18 00:06:00Z>},
%{a: 3, cluster: 0, time: #DateTime<2018-02-18 00:09:00Z>},
%{a: 4, cluster: 1, time: #DateTime<2018-02-18 00:12:00Z>},
%{a: 5, cluster: 1, time: #DateTime<2018-02-18 00:15:00Z>},
%{a: 6, cluster: 2, time: #DateTime<2018-02-18 00:18:00Z>},
%{a: 7, cluster: 2, time: #DateTime<2018-02-18 00:21:00Z>},
%{a: 8, cluster: 2, time: #DateTime<2018-02-18 00:23:00Z>},
%{a: 9, cluster: 3, time: #DateTime<2018-02-18 00:26:00Z>},
%{a: 10, cluster: 3, time: #DateTime<2018-02-18 00:29:00Z>},
%{a: 11, cluster: 3, time: #DateTime<2018-02-18 00:32:00Z>},
%{a: 12, cluster: 4, time: #DateTime<2018-02-18 00:35:00Z>},
%{a: 13, cluster: 4, time: #DateTime<2018-02-18 00:38:00Z>}
]
[
%{a:0,集群:0,时间:#DateTime},
%{a:1,集群:0,时间:#DateTime},
%{a:2,集群:0,时间:#DateTime},
%{a:3,集群:0,时间:#DateTime},
%{a:4,集群:1,时间:#DateTime},
%{a:5,集群:1,时间:#DateTime},
%{a:6,集群:2,时间:#DateTime},
%{a:7,集群:2,时间:#DateTime},
%{a:8,集群:2,时间:#DateTime},
%{a:9,集群:3,时间:#DateTime},
%{a:10,集群:3,时间:#DateTime},
%{a:11,集群:3,时间:#DateTime},
%{a:12,集群:4,时间:#DateTime},
%{a:13,集群:4,时间:#DateTime}
]
更有效的方法是在map reducer中的函数子句上使用模式匹配:
Enum.map\u reduce(数据,{0,0},fn
%{cluster:last}=x,{i,last}->
{%{x |簇:i},{i,last}
%{cluster:last}=x,{i,{}->
{%{x |簇:i+1},{i+1,last}
(完)
没门!!我很好奇。我尝试在函数的第一个参数中放入两个参数,但失败了。我不知道您可以通过元组将多个项传递到累加器中。累加器也可以进行映射吗?或者需要什么吗?从中可以看出,它需要any()
,这意味着如果需要,可以将最后一个结构完全传递给它。。。。六羟甲基三聚氰胺六甲醚。。。谢谢@Dogbert!!!是的,你可以传递任何术语。顺便说一句,我进一步简化了匿名函数中的代码。