开发者

Ruby: sorting 2d array and output similar field value to files

开发者 https://www.devze.com 2023-02-19 09:06 出处:网络
I have array which I read from excel (using ParseExcel) using the following code: workbook = Spreadsheet::ParseExcel.parse(\"test.xls\")

I have array which I read from excel (using ParseExcel) using the following code:

workbook = Spreadsheet::ParseExcel.parse("test.xls")
rows = workbook.worksheet(1).map() { |r开发者_开发知识库| r }.compact
grid = rows.map() { |r| r.map() { |c| c.to_s('latin1') unless c.nil?}.compact rescue nil }
grid.sort_by { |k| k[2]} 

test.xls has lots of rows and 6 columns. The code above sort by column 3.

I would like to output rows in array "grid" to many text file like this: - After sorting, I want to print out all the rows where column 3 have the same value into one file and so on for a different file for other same value in column3.

Hope I explain this right. Thanks for any help/tips.

ps. I search through most posting on this site but could not find any solution.


instead of using your above code, I made a test 100-row array, each row containing a 6-element array.

You pass in the array, and the column number you want matched, and this method prints into separate files rows that have the same nth element.

Since I used integers, I used the nth element of each row as the filename. You could use a counter, or the md5 of the element, or something like that, if your nth element does not make a good filename.

a = []
100.times do 
b = []
    6.times do 
    b.push rand(10)
    end
    a.push(b)
end

def print_files(a, column)

  h = Hash.new
    a.each do |element|
    h[element[2]] ? (h[element[column]] = h[element[column]].push(element)) : (h[element[column]] = [element])
  end

  h.each do |k, v|
    File.open("output/" + k.to_s, 'w') do |f|
      v.each do |line|
        f.puts line.join(", ")
      end
    end
  end
end

print_files(a, 2)


Here is the same code using blocks instead of do .. end:

a = Array.new
100.times{b = Array.new;6.times{b.push rand(10)};a.push(b)}

def print_files(a, column)
  h = Hash.new
  a.each{|element| h[element[2]] ? (h[element[column]] = h[element[column]].push(element)) : (h[element[column]] = [element])}
  h.map{|k, v| File.open("output/" + k.to_s, 'w'){|f| v.map{|line| f.puts line.join(", ")}}}
end

print_files(a, 2)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号