Ruby:删除最后一个迭代项目?

时间:2010-01-08 15:29:24

标签: ruby file-io

我正在做的是:将一个文件作为输入,将另一个文件作为输出。我在输入中选择了一个随机行,将其放在输出中,然后将其删除。

现在,我已经迭代了文件并且我想要的就行了。我已将其复制到输出文件中。有没有办法删除它?我正在做这样的事情:

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,但我不确定如何从源文件中删除它。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

这是一个随机线类。您可以通过传递输入文件名和输出文件名来创建新的随机对象。然后,您可以在该对象上调用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)

答案 2 :(得分:0)

您必须在删除一行后重新写入源文件,否则修改将不会因为它们在数据副本上执行而停留。

请记住,如果存在任何排序错误且操作无法完成,任何就地修改文件的操作都会有截断文件的风险。

使用某种简单的数据库来处理这种事情会更安全,因为像SQLite和BDB这样的库有确保数据完整性的方法,但是如果这不是一个选项,那么在编写新输入时你需要小心文件。