如何做Enum.sort_by和使用created_at日期搜索Elixir

时间:2019-03-07 06:24:51

标签: elixir

我有此数据,

[       
  %{
    company_id: "ocsc.ie",
    created_at: "Wednesday, 08 Mar 2017  6:14 AM",
    name: "O'Connor Sutton Cronin",
    session_count: 2,
    user_count: 8
  },
  %{
    company_id: "virtuspm.ie",
    created_at: "Tuesday, 10 Jul 2018  8:48 AM",
    name: "VIRTUS",
    session_count: 1,
    user_count: 7
  },
  %{
    company_id: "garlandconsultancy.com",
    created_at: "Wednesday, 20 Jun 2018  3:32 PM",
    name: "Garland",
    session_count: 1,
    user_count: 3
  },
  %{
    company_id: "protectorsecurity.co.uk",
    created_at: "Friday, 31 Aug 2018 11:03 AM",
    name: "Protector Security Group",
    session_count: 4,
    user_count: 9
  },
  %{
    company_id: "tcd.ie",
    created_at: "Wednesday, 01 Mar 2017  7:39 AM",
    name: "TCD",
    session_count: 4,
    user_count: 18
  }
]

我正在尝试根据不同的值对此进行排序。

 Enum.sort_by(data, &(&1.user_count), &Kernel.>=/2)

整数和字符串都使用,上面的表达式有效。

我已经尝试过使用整数值,但我担心的是如何按日期排序? 另外,我们可以搜索值吗? like表达式?仅适用于namecompany_id,在其中您将搜索查询传递为gar

  [%{
    company_id: "garlandconsultancy.com",
    created_at: "Wednesday, 20 Jun 2018  3:32 PM",
    name: "Garland",
    session_count: 1,
    user_count: 3
  }]

。 因此,所有与搜索查询相似的地图都会被过滤。

我已经尝试过

Enum.filter(data, fn(x) -> String.match?(String.downcase(x.name), ~r/String.downcase("VIR")/) end)

它也不起作用。任何帮助都会令人感激。

3 个答案:

答案 0 :(得分:1)

最简单的方法是使用Timex之类的库来首先删除所有日期时间字符串。

您可以使用指令削减日期以适合您的特定格式。

def parse_timestamp(ts) do 
  Timex.parse!(ts, "{WDfull}, {0D} {Mshort} {YYYY}  {h12}:{m} {AM}")
end

例如:

iex(1)> parse_timestamp("Tuesday, 10 Jul 2018  8:48 AM")
~N[2018-07-10 08:48:00]

然后您可以通过调用以下值来使用这些值对数据进行排序:

data 
|> Enum.sort_by(fn d -> d.created_at |> parse_timestamp() end, &Timex.before?/2)

答案 1 :(得分:1)

尽管Enum documentation声明了Christophe在答案中已经写的内容,但是它不起作用,因为它将引发错误**(CaseClauseError)没有大小写子句匹配::gt **

如果您遇到相同的问题,则需要为:gt /:lt值显式调用true和false

data
|> Enum.sort(fn map1, map2 -> 
  case DateTime.compare(map1[date_key], map2[date_key]) do
    :lt -> true
    _ -> false
  end
end)

这以date_key的升序对数据进行排序。另外,我没有包括解析日期的步骤,您可以参考上面的书面答案。

答案 2 :(得分:0)

关于第二个问题,您必须插值String.downcase("VIR")

Enum.filter(data, fn x ->
      to_find = String.downcase("VIR")
      String.match?(String.downcase(x.name), ~r/#{to_find}/)
    end)

在这种情况下,您可以使用String.contains?/2代替String.match?/2

为了进行时间比较,请使用Timex库(如denis.peplin在评论中所述)