2010-09-11 3 views
2

Je suis désolé si cette question est stupide, mais je dois demander. En PHP, nous pouvons créer un tableau sans le déclarer en premier, bien qu'il ne soit pas considéré comme une bonne pratique. En pratiquant ma nouvelle connaissance de Ruby, j'écrivais un code pour lister les fichiers dans un répertoire et les trier par leurs extensions. Pour ce faire, j'ai démarré une boucle pour les mettre dans différents tableaux en fonction de leurs extensions. Comme ceci:Créer un tableau sans le déclarer en premier - Ruby

files_by_ext = {} #edited - my bad, it was supposed to be {} 
files_by_ext['css'] = ['file.css','file2.css','file3.css'] 
files_by_ext['html'] = ['file.html','file2.html','file3.html'] 

Ensuite, je voudrais trier en utilisant les touches 'css' et 'html'. Mais dans le processus de création du tableau de fichiers "X", j'ai eu besoin de vérifier si la clé "X" existait. Je ne pouvais pas simplement pousser le fichier (par exemple 'fichier.X').

Il existe un moyen de créer des méthodes pour modifier ce comportement, afin que je puisse créer un tableau en poussant un élément sans le déclarer en premier?

files.each do |f| 
extension = /\.(.+)$/.match(f)[1].to_s 
files_by_ext[extension] << f 
end 

Et pas (c'est ce que je fais):

files.each do |f| 
extension = /\.(.+)$/.match(f)[1].to_s 
if !files_by_ext.key?(extension) 
    files_by_ext[extension] = [f] 
else 
    files_by_ext[extension] << f 
end 
end 

Je suis désolé, je pense que je l'ai écrit trop. : P Merci d'avoir lu.

Répondre

1

Pour définir une valeur par défaut de Array.new, vous devez passer un Hash.new à un bloc et affecter un nouveau tableau au hachage chaque fois qu'une nouvelle clé est utilisée. Ceci est la seule bonne façon de le faire:

files_by_ext = Hash.new { |hsh, key| hsh[key] = Array.new } 

Vous pouvez alors utiliser les touches dans ce hachage comme si chaque clé a déjà un tableau en elle.

files_by_ext['.com'] << 'command.com' 

Une autre approche qui est très couramment utilisée consiste à effectuer les opérations suivantes:

files_by_ext = Hash.new 
# ... later ... 
files_by_ext['.com'] ||= Array.new 
files_by_ext['.com'] << 'command.com' 
+0

Je comprends. La difficulté que j'ai est d'adapter ma méthode de pensée. Différentes ressources, après tout. En tout cas, merci pour votre réponse, beaucoup aidé. Je n'ai pas justifié dans ma question, mais j'ai utilisé des chaînes comme clé parce que je ne pouvais pas penser à un moyen d'obtenir l'extension et de le transformer en symbole. C'est possible? –

+0

Oui, vous pouvez utiliser '' string'.to_sym', mais j'utiliserais juste une chaîne ici. Je pense que cela a plus de sens, car ce sont des extensions de fichiers, qui sont intrinsèquement des chaînes. Les chaînes fonctionnent très bien comme des clés de hachage - en fait, vous pouvez utiliser _any object_ comme une clé de hachage. – wuputah

0

Je ne suis pas sûr que je vous ai bien compris, mais cela ressemble un peu à la valeur par défaut d'une entrée qui serait un tableau vide. Par exemple, il semble qu'une solution propre serait de créer un hachage dans lequel toutes ses entrées par défaut à un tableau vide, au lieu de zéro. Dans Ruby, vous le faites comme suit:

>> h = Hash.new { |hash, key| hash[key] = Array.new } 
{} 
>> h[:foo] << "stuff" 

Cela permettrait d'éliminer votre besoin de vérifier si une entrée existe avant d'ajouter à elle.

+0

Cela ne fonctionnera pas; le tableau par défaut est toujours modifié si vous le faites de cette façon. – wuputah

+0

wow, bon appel. Je n'avais pas réalisé que puisque ce n'est pas quelque chose que j'ai tendance à utiliser.mis à jour le post donc c'est au moins correct – Pete

+0

Merci pour votre temps et réponse, vous avez bien compris ma question. 8D –

0

Alors, deux choses:

Contrairement à PHP, Ruby fait la différence entre les tableaux (Array classe) et des tableaux associatifs (classe Hash). Vous avez besoin du type de structure key-> value, vous devez utiliser Hash, auquel vous accéderez par extension de fichier. Les valeurs de votre hash peuvent être des tableaux de noms de fichiers.

Toutefois, vous ne souhaitez pas que les noms de fichiers soient dupliqués dans ces valeurs. Vous devez donc utiliser la classe Set au lieu de Array. De cette façon, vous n'avez pas besoin de vous inquiéter si vous avez déjà le même nom de fichier déjà inséré.

D'autres ont déjà écrit sur la définition de la valeur par défaut d'un Hash.

+0

Je vais examiner cela, merci pour le pourboire! –

Questions connexes