2017-01-14 21 views
6

Przygotowałem mały scenariusz, aby pomóc mi w odzyskaniu kontuzji. Wydaje się to, czego się spodziewam, jednak daty nie wydają się sortować tak, jak się spodziewałem - wygląda na to, że sortowanie według miesiąca/dnia działa, ale nie rok. Ten sam wynik, jeśli sortuję tylko listę dat i nie używam struktury.Sortowanie listy dat w eliksiru

Notatka boczna, używając https://github.com/lau/calendar do wypełnienia mojego zakresu dat.

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 

bieganie w IEX wyprowadza następujące:

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}] 

Odpowiedz

9

Wydaje się, że data struct z biblioteki używasz wygląda następująco: %Date{day: 25, month: 12, year: 2014}. W strukturach Elixir są porównywane według ich zawartości, w kolejności alfabetycznej pól. W tym przypadku najistotniejsze będzie: day, następnie month i year - przeciwieństwo tego, czego szukasz.

Możesz spróbować zmienić Enum.sort_by(values, &(&1.day)) na Enum.sort_by(values, &(Date.to_erl(&1.day))). Spowoduje to przekształcenie struktury %Date{} w krotkę Erlanga, która powinna zostać posortowana zgodnie z oczekiwaniami.

+0

To było wspaniałe! Dzięki –

+0

Działa dla mnie, dziękuję! @JaredKnipp można oznaczyć jako poprawną odpowiedź? – Mickey

0

można użyć Calendar.Date.before też:

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

z Elixir.Date:

Enum.sort(values, fn x, y -> 
    case Date.compare(x.day, y.day) do 
    :lt -> true 
    _ -> false 
    end 
end) 
Powiązane problemy