创建数组而不首先声明它 - Ruby

时间:2010-09-11 02:19:03

标签: ruby arrays on-the-fly

如果这个问题很愚蠢,我很抱歉,但我必须问。 在PHP中,我们可以创建一个数组而不首先声明它,虽然它不被认为是好的实践。 练习我对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']

然后我会使用键'css'和'html'排序。但是在创建“X”文件数组的过程中,我需要验证密钥“X”是否存在。我不能简单地推送文件(例如'file.X')。

有一种方法可以创建方法来改变这种行为,这样我就可以创建一个推送项目的数组而不首先声明它吗?

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

而不是(这就是我正在做的):

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

对不起,我觉得我写的太多了。 :P谢谢你的阅读。

3 个答案:

答案 0 :(得分:1)

为了设置默认值Array.new,您必须传递Hash.new一个块,并在每次使用新密钥时将新数组分配给哈希。这是唯一正确的方法:

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

然后,您可以使用该哈希中的密钥,就像每个密钥中都有一个数组一样。

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

一种非常常用的替代方法是执行以下操作:

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

答案 1 :(得分:0)

我并不肯定我理解正确,但听起来有点像你想要将条目的初始值默认为空数组。例如,听起来像一个干净的解决方案是创建一个哈希,其中所有条目默认为空数组,而不是nil。在Ruby中,您可以按如下方式执行此操作:

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

这样就无需在附加条目之前检查条目是否存在。

答案 2 :(得分:0)

所以,有几件事:

与PHP不同,Ruby在数组(Array类)和关联数组(Hash类)之间产生差异。您需要key-&gt;值类型的结构,您应该使用Hash,您将通过文件扩展名访问它。哈希值可以是文件名数组。

但是,您不希望文件名在这些值中重复,因此您应该考虑使用Set类而不是Array。这样,如果您已经插入了相同的文件名,则无需担心。

其他人已经写过关于设置Hash的默认值的文章。