6
votes

Comment faire une matrice multi-dimensionnelle dynamique dans Ruby?

J'ai une question de rubis débutant sur des tableaux multidimensionnels.

Je veux trier les entrées d'ici année et par mois. Je tiens donc à créer un tableau multidimensionnel qui contiendrait des années -> mois -> entrées de mois p>

de sorte que le tableau serait comme: p> xxx pré>

Maintenant, j'ai: p>

@years = []
@entries.each do |entry|
    timeobj = Time.parse(entry.created_at.to_s)
    year = timeobj.strftime("%Y").to_i
    month = timeobj.strftime("%m").to_i
    @years[year][month] << entry
end


0 commentaires

4 Réponses :


10
votes

Vous obtenez l'erreur parce qu'un fixnum code> (c'est-à-dire un numéro) est enfoncé sur la matrice, dans la ligne qui lit @ ans.push (année) code> .

Votre approche d'utilisation des tableaux pour commencer est un peu défectueux; Un tableau est parfait pour contenir une liste ordonnée d'articles. Dans votre cas, vous avez un mappage des clés des valeurs, ce qui est parfait pour un hachage. P>

Au premier niveau, les clés sont des années, les valeurs sont des haubes. Les hachages du deuxième niveau contiennent des clés de mois et des valeurs de réseaux d'entrées. P>

Dans ce cas, une sortie typique de votre code ressemblerait à quelque chose comme (en fonction de votre exemple): P>

@years = {}
@entries.each do |entry|
  timeobj = Time.parse(entry.created_at.to_s)
  year = timeobj.strftime("%Y").to_i
  month = timeobj.strftime("%m").to_i
  @years[year] ||= {} # Create a sub-hash unless it already exists
  @years[year][month] ||= []
  @years[year][month] << entry
end


3 commentaires

Merci pour moi éclairer.


Je t'en prie. Regardez la réponse de Michael_sepot pour comment faire dans un autre Rubyish .


Merci! Enfin je comprends cela



3
votes

J'utilise des tables de hasch au lieu de tableaux, car je pense que cela a probablement plus de sens ici. Cependant, il est assez trivial de revenir à l'utilisation des tableaux si c'est ce que vous préférez.

entries = [
    [2009, 8, 1],
    [2009, 8, 2],
    [2009, 9, 3],
    [2007, 10, 5]
]

years = Hash.new
entries.each { |e|
    year = e[0]
    month = e[1]
    entry = e[2]

    # Add to years array
    years[year] ||= Hash.new
    years[year][month] ||= Array.new
    years[year][month] << entry
}

puts years.inspect


0 commentaires

3
votes
# create a hash of hashes of array
@years = Hash.new do |h,k|
  h[k] = Hash.new do |sh, sk|
    sh[sk] = []
  end
end

@entries.each do |entry|
  timeobj = Time.parse(entry.created_at.to_s)
  year = timeobj.year
  month = timeobj.month
  @years[year][month] << entry
end

0 commentaires

7
votes

Vous pouvez obtenir la structure de matrice imbriquée en une ligne en utilisant une combinaison de group_by s et carte : xxx


2 commentaires

N'est-ce pas un ajout de groupe_by, pas un vieux ruby?


Ah - J'essayais sur Ruby 1.8.6.