Как найти похожие строки в двух файлах CSV? - PullRequest
1 голос
/ 01 февраля 2012

Вот мой код, но для огромных файлов он вечен:

require 'rubygems'
require "faster_csv"

fname1 =ARGV[0]
fname2 =ARGV[1]
if ARGV.size!=2
    puts "Display common lines in the two files \n Usage : ruby user_in_both_files.rb <file1> <file2> "
    exit 0
end

puts "loading the CSV files ..."
file1=FasterCSV.read(fname1, :headers => :first_row)
file2=FasterCSV.read(fname2, :headers => :first_row)
puts "CSV files loaded"

#puts file2[219808].to_s.strip.gsub(/\s+/,'')

lineN1=0
lineN2=0
# count how many common lines
similarLines=0
file1.each do |line1|
    lineN1=lineN1+1
    #compare line 1 to all line from file 2
    lineN2=0
    file2.each do |line2|
        puts "file1:l#{lineN1}|file2:l#{lineN2}"
        lineN2=lineN2+1
        if ( line1.to_s.strip.gsub(/\s+/,'') == line2.to_s.strip.gsub(/\s+/,'') ) 
            puts "file1:l#{line1}|file2:l#{line2}->#{line1}\n"
            similarLines=similarLines+1
        end
    end 
end
puts "#{similarLines} similar lines."

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

В Ruby есть множество операций, доступных с массивами:

a_ary = [1,2,3]
b_ary = [3,4,5]
a_ary & b_ary # => 3

Итак, из этого вы должны попробовать:

puts "loading the CSV files ..."
file1 = FasterCSV.read(fname1, :headers => :first_row)
file2 = FasterCSV.read(fname2, :headers => :first_row)
puts "CSV files loaded"

common_lines = file1 & file2
puts common_lines.size

Если вам нужно предварительно обработать массивы, делайте это при загрузкеих:

file1 = FasterCSV.read(fname1, :headers => :first_row).map{ |l| l.to_s.strip.gsub(/\s+/, '') }
file2 = FasterCSV.read(fname2, :headers => :first_row).map{ |l| l.to_s.strip.gsub(/\s+/, '') }
1 голос
/ 01 февраля 2012

Вы gsub используете File2 каждый раз, когда просматриваете File1. Сначала я бы это сделал, а потом просто сравнил результаты.

Редактировать Как-то так (не проверено)

file1lines = []
file1.each do |line1|
  file1lines = line1.strip.gsub(/\s+/, '')
end

# Do the same for `file2lines`

file1lines.each do |line1|     
  lineN1=lineN1+1     
  #compare line 1 to all line from file 2     
  lineN2=0     
  file2lines.each do |line2|     
    puts "file1:l#{lineN1}|file2:l#{lineN2}"     
    lineN2=lineN2+1     
    if ( line1 == line2 )      
        puts "file1:l#{line1}|file2:l#{line2}->#{line1}\n"     
        similarLines=similarLines+1     
    end     
  end      
end     

Я бы также избавился от всех puts в циклах, если они вам действительно не нужны. Если файлы огромные, это, вероятно, замедляет их заметное количество.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...