2017-01-14 11 views
6

私は傷害回復プロセスを手助けする小さなスクリプトをまとめました。私が期待しているものを出力しますが、日付はソートされていないと思われます。月/日単位のソートが動作しているようですが、年単位ではありません。私が日付のリストだけをソートし、構造体を使用しないのであれば、同じ結果になります。エリクシールの日付の並べ替え

サイドノート、https://github.com/lau/calendarを使用して日付範囲を設定します。 IEXで実行

defmodule Phase do 
    defstruct day: "", weight: "" 
end 

defmodule Recovery do 
    alias Calendar.Date 

    def phases(start_date, end_date, start_weight, increase_by) do 
    # Get the range of dates 
    date_range = Date.days_after_until(start_date, end_date, true) |> Enum.to_list 

    # build all phases, starting at day 0 
    values = do_phases(date_range, [], start_weight, increase_by) 
    Enum.sort_by(values, &(&1.day)) 
    end 

    defp do_phases([], recovery_plan, _weight, _increase_by), do: recovery_plan 
    defp do_phases([head | tail], recovery_plan, weight, increase_by) do 
    v = [%Phase{day: head, weight: weight} | recovery_plan] 
    do_phases(tail, v, weight + increase_by, increase_by) 
    end 
end 

次を出力します

iex(18)> d1 = Date.from_erl! {2016, 12, 29} 
iex(19)> d2 = Date.from_erl! {2017, 1, 19} 
iex(24)> Recovery.phases(d1, d2, 30, 5) 
[%Phase{day: ~D[2017-01-01], weight: 45}, 
%Phase{day: ~D[2017-01-02], weight: 50}, 
%Phase{day: ~D[2017-01-03], weight: 55}, 
%Phase{day: ~D[2017-01-04], weight: 60}, 
%Phase{day: ~D[2017-01-05], weight: 65}, 
%Phase{day: ~D[2017-01-06], weight: 70}, 
%Phase{day: ~D[2017-01-07], weight: 75}, 
%Phase{day: ~D[2017-01-08], weight: 80}, 
%Phase{day: ~D[2017-01-09], weight: 85}, 
%Phase{day: ~D[2017-01-10], weight: 90}, 
%Phase{day: ~D[2017-01-11], weight: 95}, 
%Phase{day: ~D[2017-01-12], weight: 100}, 
%Phase{day: ~D[2017-01-13], weight: 105}, 
%Phase{day: ~D[2017-01-14], weight: 110}, 
%Phase{day: ~D[2017-01-15], weight: 115}, 
%Phase{day: ~D[2017-01-16], weight: 120}, 
%Phase{day: ~D[2017-01-17], weight: 125}, 
%Phase{day: ~D[2017-01-18], weight: 130}, 
%Phase{day: ~D[2017-01-19], weight: 135}, 
%Phase{day: ~D[2016-12-29], weight: 30}, 
%Phase{day: ~D[2016-12-30], weight: 35}, 
%Phase{day: ~D[2016-12-31], weight: 40}] 

答えて

9

それはあなたがこのようになります使用しているライブラリーから日付の構造体のように思える:%Date{day: 25, month: 12, year: 2014}を。エリクシール構造体では、フィールドのアルファベット順に内容が比較されます。この場合、最も重要なものはdayとなり、次にmonthyear - あなたが探しているものの反対です。

Enum.sort_by(values, &(&1.day))Enum.sort_by(values, &(Date.to_erl(&1.day)))に変更してみてください。これにより、構造体を%Date{}構造体をErlangタプルに変換します。このタプルは期待どおりにソートされます。

+0

が素晴らしい働いたこと!ありがとう –

+0

私のために働く、ありがとう! @ JaredKnippあなたは正しい答えとしてこれをマークできますか? – Mickey

0

あなたもCalendar.Date.beforeを使用することができます。

Enum.sort(values, fn x, y -> Calendar.Date.before?(x.day, y.day) end) 

Elixir.Dateで:

Enum.sort(values, fn x, y -> 
    case Date.compare(x.day, y.day) do 
    :lt -> true 
    _ -> false 
    end 
end) 
関連する問題