Ordonnancement tableau depuis hash

Bonjour,

Il y a quelques temps, j’ai pu voir que certains ici étaient très fort
pour ordonner des tableaux. Ne trouvant pas comment m’y prendre pour
classer correctement un hash, je viens demander vos lumières :

Voici déjà le hash :

:fields => {:login => { “fieldname” => “Login”, “pos” => 3 }, :firstname
=> { “fieldname” => “Nom”, “pos” => 1 }, :lastname => { “fieldname” =>
“Prénom”, “pos” => 2 }, :email => { “fieldname” => “Email”,
“vtype” => “email”, “pos” => 4 }, :address => { “fieldname” =>
“Adresse”, “pos” => 5 }}

Ce hash est ensuite utilisé en diverses occasions donc une fonction sur
laquelle je sors les clés que je groupe par 2 dans un tableau. CelÃ
donne le code suivant :

requested_attributes = options[:fields].keys.in_groups_of(2)

Avant d’ajouter le “pos”, ce tableau me classait mes éléments par ordre
alphabétique (:address, :email, :firstname, :lastname, :login) , mon but
est de permettre de choisir l’ordre d’apparition de mes champs en
fonction de ce “pos”.

J’ai tenté avec sort_by sans vraiment de succès, j’imagine que je
l’emploi assez mal.

Merci.

Bonjour

Un hash n’est pas fait pour être ordonné, tu dois donc ordonner ses
clés préalablement.
Par exemple pour ce que tu veux faire, essaie:
f=options[:fields]
requested_attributes = f.keys.sort_by{ |k| f[k][“pos”] }.in_groups_of(2)

Le 19 juin 2008 10:51, Tony C. [email protected] a écrit
:

=> { “fieldname” => “Nom”, “pos” => 1 }, :lastname => { “fieldname” =>
alphabétique (:address, :email, :firstname, :lastname, :login) , mon but


Baptiste

Le 19 juin 2008 16:51, Tony C. a écrit :

“Adresse”, “pos” => 5 }}

J’ai tenté avec sort_by sans vraiment de succès, j’imagine que je
l’emploi assez mal.

Si j’ai bien compris le problème :

ary = options[:fields].sort_by { |_, v| v[‘pos’] }.map(&:first)
requested_attributes = ary.in_groups_of(2)

devrait obtenir ce que tu veux.

– Jean-François.


http://twitter.com/underflow_

Jean-François Trân wrote:

Le 19 juin 2008 16:51, Tony C. a �crit :

“Adresse”, “pos” => 5 }}

J’ai tent� avec sort_by sans vraiment de succ�s, j’imagine que je
l’emploi assez mal.

Si j’ai bien compris le probl�me :

ary = options[:fields].sort_by { |_, v| v[‘pos’] }.map(&:first)
requested_attributes = ary.in_groups_of(2)

devrait obtenir ce que tu veux.

– Jean-Fran�ois.


http://twitter.com/underflow_

Merci beaucoup, c’est exactement celà . A quoi correspond ce “_” dans le
block de sort_by ?

Ceci semble fonctionner chez moi, si j’ai bien compris ta demande :

irb(main):001:0> options = {:fields => {:login => { “fieldname” =>
“Login”, “pos” => 3 }, :firstname => { “fieldname” => “Nom”, “pos” => 1
}, :lastname => { “fieldname” => “Prénom”, “pos” => 2 }, :email
=> { “fieldname” => “Email”, “vtype” => “email”, “pos” => 4 }, :address
=> { “fieldname” => “Adresse”, “pos” => 5 }}}
=> {:fields=>{:email=>{“pos”=>4, “vtype”=>“email”,
“fieldname”=>“Email”}, :address=>{“pos”=>5, “fieldname”=>“Adresse”},
:login=>{“pos”=>3, “fieldname”=>“Login”}, :firstname=>{“pos”=>1,
“fieldname”=>“Nom”}, :lastname=>{“pos”=>2,
“fieldname”=>“Prénom”}}}

irb(main):002:0> options[:fields].sort_by{ |field| field[1][“pos”] }
=> [[:firstname, {“pos”=>1, “fieldname”=>“Nom”}], [:lastname, {“pos”=>2,
“fieldname”=>“Prénom”}], [:login, {“pos”=>3,
“fieldname”=>“Login”}], [:email, {“pos”=>4, “vtype”=>“email”,
“fieldname”=>“Email”}], [:address, {“pos”=>5, “fieldname”=>“Adresse”}]]

En revanche je n’ai pas très bien compris pourquoi sort_by oblige le
passage à un tableau de “|field|”, mais quelqu’un pourra peut-être
détailler ça. Le champ email par exemple est “transformé” comme suit Ã
l’intérieur du bloc sort_by : [:email, {“pos”=>4, “vtype”=>“email”,
“fieldname”=>“Email”}]:Array, ce qui oblige à prendre le “[1]”, mais il
y a peut-être plus propre ou joli je ne sais pas.

Cdt,

Jean-Baptiste

Tony C. a écrit :

Le 19 juin 2008 17:11, Baptiste D. a écrit :

Un hash n’est pas fait pour être ordonné, tu dois donc ordonner ses
clés préalablement.

2 remarques :

  • Les tables de hachage sont ordonnés dans Ruby 1.9.

  • Il y a déjà à la disposition une classe de table de hachage
    ordonnée dans Rails avec ActiveSupport::OrderedHash si
    on en a besoin.

    – Jean-François.


http://twitter.com/underflow_

Le 19 juin 2008 17:18, Tony C. a écrit :

ary = options[:fields].sort_by { |_, v| v[‘pos’] }.map(&:first)
requested_attributes = ary.in_groups_of(2)

devrait obtenir ce que tu veux.

Merci beaucoup, c’est exactement celà. A quoi correspond ce “_” dans le
block de sort_by ?

Ben c’est un paramètre de bloc :slight_smile:

Il y a plusieurs conventions de rubyistes :

  • la première c’est d’appeler ses arguments k et v car on est fainéant
    d’écrire key et value qui seraient plus explicites.

  • la seconde est d’utiliser _ pour un argument ou une variable
    dont on ne se servira pas. C’est une manière de dire : je m’en
    tape le caribou de la variable _. On peut très bien l’utiliser,
    mais dans ce cas on aurait pris un nom de variable plus parlant,
    à moins de faire de l’obfuscated Ruby. Ici, je n’ai besoin que de
    v.

Mais si une variable est inutile, ça ne sert à rien de lui donner
un nom (moins anonyme que _ car _ est en fait aussi un nom),
car nommer est difficile. Je sais pas si c’est clair ?

Plusieurs remarques annexes :

  • on peut très bien avoir une variable d’instance @_ :

class Escargot
attr_reader :_

def initialize(message)
@_ = message
end
end

puts Escargot.new(‘@_ ressemble a un escargot, non ?’)._

  • Autre convention parfois utilisée, les méthodes commençant
    par _ sont des méthodes privées.

  • Tu as Object#id et Object#send qui sont des méthodes
    un peu particulières. (Heureusement on abuse moins que Python
    des méthodes commençant par __ (getattr, init, delitem,
    hash …))

  • Rails utilise certaines variables d’instance pour AC::B et AV::B
    @_session, @_response, @_params, etc. via le mécanisme attr_internal.

  • $_ est particulier.

    – underflow_


http://twitter.com/underflow_

Effectivement, merci pour le rappel et désolé pour le ton
rétrospectivement un peu trop didactique qui n’était pas voulu.

Le 19 juin 2008 18:26, Jean-François Trân [email protected] a écrit :

ordonnée dans Rails avec ActiveSupport::OrderedHash si
on en a besoin.

– Jean-François.


http://twitter.com/underflow_


Baptiste