2017-01-14 18 views
6

Yaralanma kurtarma işleminde bana yardımcı olacak küçük bir senaryo hazırladım. Beklediğim sonuçları verir, ancak tarihler beklediğim gibi sıralama yapmazlar - ay/güne göre sıralama yapar, ancak yıllara göre değil. Aynı sonucu yalnızca bir tarih listesini sıralıyorum ve bir struct kullanmıyorsam.Elixir'deki Tarihlerin Sıralama Listesi

Tarih notumu doldurmak için https://github.com/lau/calendar kullanarak yan not. Böyle

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

cevap

9

Bu kütüphaneden tarih yapı gibi görünüyor kullandığınız görünüyor: IEX içinde Koşu

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 

aşağıdaki verir %Date{day: 25, month: 12, year: 2014}. Elixir yapılarında, içerikleri, alanların alfabetik sıralarıyla karşılaştırılır. Bu durumda, en önemlisi day, daha sonra month ve year olacaktır - aradığınız şeyin tam tersi.

Yapmaya çalıştığınız şey Enum.sort_by(values, &(&1.day)) değerini Enum.sort_by(values, &(Date.to_erl(&1.day))) olarak değiştirmektir. Bu, %Date{} yapısını, beklendiği gibi sıralanmalı Erlang tuple dönüştürecektir.

+0

amele büyük ki! Teşekkürler –

+0

Benim için çalışıyor, teşekkürler! @JaredKnipp bunu doğru cevap olarak işaretleyebilir misiniz? – Mickey

0

siz de Calendar.Date.before kullanabilirsiniz:

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

Elixir.Date ile:

Enum.sort(values, fn x, y -> 
    case Date.compare(x.day, y.day) do 
    :lt -> true 
    _ -> false 
    end 
end) 
İlgili konular