我有一些大的固定宽度文件,我需要删除标题行。
跟踪迭代器似乎不是很惯用。
# This is what I do now.
File.open(filename).each_line.with_index do |line, idx|
if idx > 0
...
end
end
# This is what I want to do but I don't need drop(1) to slurp
# the file into an array.
File.open(filename).drop(1).each_line do { |line| ... }
这是什么Ruby成语?
答案 0 :(得分:7)
这是略微整洁:
File.open(fname).each_line.with_index do |line, lineno|
next if lineno == 0
# ...
end
或
io = File.open(fname)
# discard the first line
io.gets
# process the rest of the file
io.each_line {|line| ...}
io.close
答案 1 :(得分:5)
如果您不止一次需要,可以写一个Enumerator
的扩展名。
class Enumerator
def enum_drop(n)
with_index do |val, idx|
next if n == idx
yield val
end
end
end
File.open(testfile).each_line.enum_drop(1) do |line|
print line
end
# prints lines #1, #3, #4, …
答案 2 :(得分:2)
现在您已经得到了合理的答案,这是一种完全不同的方式来处理它。
class ProcStack
def initialize(&default)
@block = default
end
def push(&action)
prev = @block
@block = lambda do |*args|
@block = prev
action[*args]
end
self
end
def to_proc
lambda { |*args| @block[*args] }
end
end
#...
process_lines = ProcStack.new do |line, index|
puts "processing line #{index} => #{line}"
end.push do |line, index|
puts "skipping line #{index} => #{line}"
end
File.foreach(filename).each_with_index(&process_lines)
这不是惯用的,也不是第一次非常直观,但它很有趣!
答案 3 :(得分:1)
脱离我的头脑,但我相信更多的研究会有更优雅的方式
File.open( filename ).each_line.to_a[1..-1].each{ |line|... }
好的从头开始......做了一些研究,这可能会更好
File.open( filename ).each_line.with_index.drop_while{ |line,index| index == 0 }.each{ |line, index| ... }
答案 4 :(得分:1)
我怀疑这是惯用的,但很简单。
f = File.open(filename)
f.readline
f.each_line do |x|
#...
end
答案 5 :(得分:1)
我认为你正确地使用Enumerator和drop(1)。出于某种奇怪的原因,虽然Enumerable定义了#drop,但Enumerator却没有。这是一个有效的枚举器#drop:
class Enumerator
def drop(n_arg)
n = n_arg.to_i # nil becomes zero
raise ArgumentError, "n must be positive" unless n > 0
Enumerator.new do |yielder|
self.each do |val|
if n > 0
n -= 1
else
yielder << val
end
end
end
end
end