2

如果这个问题很愚蠢,我很抱歉,但我必须问。在 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 谢谢你的阅读。

4

3 回答 3

1

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

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

然后,您可以使用该哈希中的键,就好像每个键中已经有一个数组一样。

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

An alternative approach which is very commonly used is to do the following:

files_by_ext = Hash.new
# ... later ...
files_by_ext['.com'] ||= Array.new
files_by_ext['.com'] << 'command.com'
于 2010-09-11T02:43:46.800 回答
0

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

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

这将消除您在附加条目之前检查条目是否存在的需要。

于 2010-09-11T02:32:41.847 回答
0

So, couple of things:

Unlike in PHP, Ruby makes difference between arrays (Array class) and associative arrays (Hash class). You need key->value type of structure, you should use Hash, which you will access by file extension. Values of your hash can be arrays of filenames.

However, you don't want filenames duplicated within these values, so you should consider using Set class instead of Array. That way you don't need to worry if you already have the same filename already inserted.

Others already wrote about setting the default value of a Hash.

于 2010-09-11T05:35:24.213 回答