我正在编写一个小脚本来检查文件夹中的重复文件。我做了数组,我成功了。问题是我也想存储文件夹位置,所以我可以看到重复文件的位置。
我的第一个想法是使用哈希。但是由于你在同一个文件夹中会有很多文件,我不能这样做:hash [folder] = file。反过来也是impossivel,因为如果我有重复文件,它们将被覆盖(hash [file] =文件夹)
那么最好的办法是什么?
我的代码:
class FilesList
attr_accessor :elements
def initialize(path)
@elements = Hash.new
@path = path
printDirectory(@path)
end
def printDirectory(folderPath)
entries = Dir.entries(folderPath) - [".", "..", "repeat.rb"]
entries.each do |single|
if File.directory?("#{folderPath}/#{single}")
printDirectory("#{folderPath}/#{single}")
else
@elements[single] = folderPath
end
end
end
def printArray
puts @elements
end
def each()
@elements.each do |x, y|
yield x y
end
end
def checkRepeated
if @elements.length == @elements.keys.uniq.length
puts "No repeated Files"
else
counts = Hash.new(0)
@elements.each do |key,val|
counts[val] += 1
end
repeateds = counts.reject{|val,count|count==1}.keys
puts repeateds
end
end
end
array = FilesList.new(Dir.pwd)
array.printArray
答案 0 :(得分:1)
您可以将文件名(或文件夹路径)的数组(或sets)存储为哈希值
例如,在您的代码中,您可以将@elements[single] = folderPath
更改为:
@elements[single] ||= []
@elements[single] << folderPath
然后,您的val
将成为符合文件的文件夹数组。
答案 1 :(得分:0)
与上述类似,但不要将文件用作密钥。
@elements = Hash.new([])
entries.each do |single|
if File.directory?("#{folderPath}/#{single}")
printDirectory("#{folderPath}/#{single}")
else
@elements[folderPath] << single
end
end
然后你会得到一些看起来像这样的东西:
{ '/path1' => ['awesome_file.rb', 'beautiful.js'],
'/path2' => ['beautiful.js', 'coffee.rb'] }
然后,如果我理解正确,你可以找到如下的重复文件:
files = @elements.values.flatten
repeateds = files.select{ |file| files.count(file) > 1 }
这将返回一个数组:["beautiful.js", "beautiful.js"]
,您可以调用.uniq
来获取["beautiful.js"
,或者根据需要进行计数,或将结果映射到另一个哈希,告诉你它重复的频率等等。