2010-01-08 75 views
0

我正在做的是:有一個文件作爲輸入,另一個作爲輸出。我在輸入中選擇了一個隨機行,將它放在輸出中,然後刪除它。Ruby:刪除上次迭代的項目?

現在,我已經遍歷該文件,並在我想要的行上。我已將其複製到輸出文件。有沒有辦法刪除它?我正在做這樣的事情:

for i in 0..number_of_lines_to_remove 
    line = rand(lines_in_file-2) + 1 #not removing the first line 
    counter = 0 
    IO.foreach("input.csv", "r") { |current_line| 
     if counter == line 
     File.open("output.csv", "a") { |output| 
      output.write(current_line) 
     } 
     end 
     counter += 1 
    } 
end 

所以,我有current_line,但我不知道如何從源文件中刪除它。

回答

1

Array.delete_at可能會這樣做。給定一個索引,它將刪除該索引處的對象,並返回該對象。

input.csv:

one,1 
two,2 
three,3 

計劃:

#!/usr/bin/ruby1.8 

lines = File.readlines('/tmp/input.csv') 
File.open('/tmp/output.csv', 'a') do |file| 
    file.write(lines.delete_at(rand(lines.size))) 
end 
p lines # ["two,2\n", "three,3\n"] 

output.csv:

one,1 
0

你必須重新編寫源文件,否則刪除行後修改不會因爲它們在數據副本上執行而保持不變。

請記住,如果存在任何類型的錯誤並且操作無法完成,則任何在原地修改文件的操作都會導致截斷文件的風險。

因爲像SQLite和BDB這樣的庫具有確保數據完整性的方法,所以使用某種簡單的數據庫對於這類事情會更安全一些,但如果這不是一種選擇,那麼在編寫新的時候就需要小心輸入文件。

+0

我不必重寫與該解決方案的來源,我只需要繼續重新使用從輸入複製的字符串它的一個例子。由於線條正在從字符串中刪除,所剩下的只是減小其總大小以匹配刪除的線條。我從來沒有用sqlite/bdb做過任何事情,所以我不知道如何繼續。我的sql知識只能選擇一些查詢。如果你有任何幫助我的例子,我會很感激。 – zxcvbnm 2010-01-08 16:04:16

+0

Beanish有一個重寫下面的文件的例子,其中更改在運行之間保存。如果你沒有使用SQL的經驗,那麼SQLite可能會被過度殺死。 – tadman 2010-01-08 16:45:11

1

這是一個randomline類。通過傳遞一個輸入文件名和一個輸出文件名來創建一個新的randomline對象。然後,您可以調用該對象的deleterandom方法並將其傳遞給多行以刪除。

數據存儲在數組內部以及存儲到文件中。目前輸出處於追加模式,所以如果您使用相同的文件,它只會添加到最後,如果您想每次都啓動新文件,則可以將a更改爲w。

class Randomline 
    attr_accessor :inputarray, :outputarray 

def initialize(filein, fileout) 
@filename = filein 
@filein = File.open(filein,"r+") 
@fileoutput = File.open(fileout,"a") 
@inputarray = [] 
@outputarray = [] 

readin() 
end 


def readin() 
@filein.each do |line| 
    @inputarray << line 
end 
end 

def deleterandom(numtodelete) 
    numtodelete.times do |num| 
    random = rand(@inputarray.size) 
    @outputarray << inputarray[random] 
    @fileoutput.puts inputarray[random] 
    @inputarray.delete_at(random) 
    end 

    @filein = File.open(@filename,"w") 
    @inputarray.each do |line| 
     @filein.puts line 
    end 

end 

end 

這裏是正在使用

a = Randomline.new("testin.csv","testout.csv") 

a.deleterandom(3)