2017-09-29 5 views
1

タスクを集中:私はドスのリスト持ってドスのリストを変換し

[ 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "a", priority: 1}}, 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "b", priority: 2}}, 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "c", priority: 3}}, 
    {%{date_value: ~D[2017-01-02], weekday: 1}, nil}, 
    {%{date_value: ~D[2017-01-03], weekday: 2}, %{todo: "d", priority: 2}}, 
] 

をしかし、私はこのようなリストが必要です。私は最初のバージョンを変換するにはどうすればよい

[ 
    %{date_value: ~D[2017-01-01], weekday: 7, tasks: [%{todo: "a", priority: 1}, 
                %{todo: "b", priority: 2}, 
                %{todo: "c", priority: 3}]}, 
    %{date_value: ~D[2017-01-02], weekday: 1, tasks: []}, 
    %{date_value: ~D[2017-01-03], weekday: 2, tasks: [%{todo: "d", priority: 2}]} 
] 

を2番目のバージョンに?

私は[head | tail]がこのリストを再帰的に歩き回って新しいリストをコンパイルする方法だと思います。しかし、私はどのようにすべてのtodoを集めて、そのような再帰でそれらをまとめて自分のリストに入れるかわからない。

答えて

3

まず、リストを日付コンポーネントでグループ化し、value関数でタスクのみを返します。これにより、日付コンポーネントからタスクのリストにマップが作成されます。次に、マップをリストに戻します。プロセス内では、サンプル出力に従ってそれらを必要としないので、nilの値も削除してください。

list = [ 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "a", priority: 1}}, 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "b", priority: 2}}, 
    {%{date_value: ~D[2017-01-01], weekday: 7}, %{todo: "c", priority: 3}}, 
    {%{date_value: ~D[2017-01-02], weekday: 1}, nil}, 
    {%{date_value: ~D[2017-01-03], weekday: 2}, %{todo: "d", priority: 2}}, 
] 

list 
|> Enum.group_by(fn {date, _} -> date end, fn {_, task} -> task end) 
|> Enum.map(fn {date, tasks} -> 
    date |> Map.put(:tasks, Enum.filter(tasks, &(&1))) 
end) 
|> IO.inspect 

出力:

[%{date_value: ~D[2017-01-01], 
    tasks: [%{priority: 1, todo: "a"}, %{priority: 2, todo: "b"}, 
    %{priority: 3, todo: "c"}], weekday: 7}, 
%{date_value: ~D[2017-01-02], tasks: [], weekday: 1}, 
%{date_value: ~D[2017-01-03], tasks: [%{priority: 2, todo: "d"}], weekday: 2}] 

(地図が順序付けられていないので、この出力はあなたの予想される出力と同じです。)