2
votes

comment faire Enum.sort_by & rechercher avec created_at date Elixir

J'ai ces données,

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

J'essaye de trier ceci en fonction de différentes valeurs.

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

Entier et chaîne à la fois, l'expression ci-dessus fonctionne.

J'ai essayé des valeurs entières, ma préoccupation est de savoir comment nous pouvons trier par date? Pouvons-nous également rechercher des valeurs? avec une expression comme ? juste pour name et company_id , où vous transmettez la requête de recherche en tant que gar.

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

. Donc, toutes ces cartes qui sont similaires à la requête de recherche filtrées.

J'ai essayé ceci

[       
  %{
    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
  }
]

Cela ne fonctionne pas non plus. Toute aide serait très reconnaissante.


4 commentaires

Utilisez hexdocs.pm/elixir/DateTime.html#compare/2 pour datetime tri, mais convertissez d'abord vos chaînes en datetimes. Essayez la bibliothèque Timex pour l'analyse datetime ( github.com/bitwalker/timex ).


et pour la recherche?


Et pour la recherche, attendez une autre réponse. Vous avez posté deux questions ici.


Si vous aimez une réponse ci-dessous, veuillez la marquer comme solution :)


3 Réponses :


0
votes

Concernant votre deuxième question, vous devez interpoler String.downcase("VIR")

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

Dans ce cas, vous pouvez utiliser String.contains? / 2 au lieu de String.match ? / 2

Pour la comparaison du temps, utilisez Timex une> bibliothèque (comme le dit denis.peplin dans les commentaires)


0 commentaires

4
votes

La voie la plus simple que vous pouvez emprunter pour analyser d'abord toutes vos chaînes datetime en utilisant une bibliothèque comme Timex.

Vous pouvez analyser une date en utilisant des directives pour l'adapter à votre format spécifique.

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

Par exemple:

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

Vous peut ensuite utiliser ces valeurs pour trier vos données en appelant:

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


2 commentaires

Mon horodatage est analysé et j'utilise le code Enum.sort_by (data, & (& 1 ["created_at"]), & DateTime.compare (& 1, & 2)) mais cela génère une erreur (CaseClauseError) aucune clause case correspondant à:: gt Qu'est-ce que je fais mal?


OK j'ai compris. Pour toute autre personne confrontée au même problème, je publie la solution finale comme une autre réponse



1
votes

Bien que la documentation Enum indique ce qui a déjà été écrit dans la réponse par Christophe mais cela ne fonctionne pas car cela générera une erreur ** (CaseClauseError) no case clause correspondant:: gt **

Si vous rencontrez le même problème, vous devrez appeler explicitement true et false pour le: gt /: lt valeur quelque chose comme ceci

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

Ceci trie les données par ordre croissant de date_key. De plus, je n'ai pas inclus les étapes d'analyse de la date pour laquelle vous pouvez vous référer à la réponse écrite ci-dessus.


1 commentaires

En fait, vous pouvez passer le nom du module DateTime au lieu d'un fn et elixir utilisera automatiquement sa fonction compare . Vous n'avez donc pas à vous lancer vous-même en booléen.