【问题标题】:Sorting list of Dates in ElixirElixir 中的日期排序列表
【发布时间】:2017-01-14 22:48:28
【问题描述】:

我编写了一个小脚本来帮助我进行伤病恢复过程。它输出我所期望的,但是日期似乎并没有像我期望的那样排序 - 看起来按月/日排序是有效的,但不是按年排序。如果我只对日期列表进行排序而不使用结构,则结果相同。

附注,使用https://github.com/lau/calendar 填充我的日期范围。

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 中运行输出如下:

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

【问题讨论】:

    标签: sorting date calendar elixir


    【解决方案1】:

    十六进制文档包括关于排序的very useful documentation,包括日期示例。您不必再传递自定义排序器函数,而是传递 Date 模块(或任何其他实现 .compare 的模块)

    dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
    Enum.sort(dates, Date)
    

    【讨论】:

      【解决方案2】:

      您正在使用的库中的日期结构看起来像这样:%Date{day: 25, month: 12, year: 2014}。在 Elixir 中,结构按其内容进行比较,按字段的字母顺序排列。在这种情况下,最重要的是 day,然后是 monthyear - 与您正在寻找的相反。

      您可以尝试将Enum.sort_by(values, &(&1.day)) 更改为Enum.sort_by(values, &(Date.to_erl(&1.day)))。这会将 %Date{} 结构转换为 Erlang 元组,该元组应按预期排序。

      【讨论】:

      • 为我工作,谢谢! @JaredKnipp 你能把它标记为正确答案吗?
      • 如何对 DateTime 结构进行排序?看起来 DateTime.to_erl 不起作用
      • 我想我会使用DateTime.to_unix,或者更好的是Enum.sort_by 与使用DateTime.compare 的自定义排序功能
      【解决方案3】:

      你也可以使用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)
      

      【讨论】:

        猜你喜欢
        • 2020-06-25
        • 2023-03-31
        • 1970-01-01
        • 2021-09-06
        • 2021-07-05
        • 2020-12-15
        • 2021-04-15
        • 1970-01-01
        • 2010-09-19
        相关资源
        最近更新 更多