На заказ написаны в Руби


Я закончила Руби главу в семь языков за семь недель. Он пытается заставить вас знакомы с основными концепциями нескольких языках довольно быстро. Я послушно сделала все упражнения, но, скорее всего, они могут быть улучшены, чтобы быть более ярко-как.

Написать простой греп, который будет печатать строки файла, имеющие любую вхождений фразы в любой точке этой линии (в моем примере 'бла'). Номера строк.

File.open( 'grepFile.txt', 'r' ) do |file|
  lines = []
  line_number = 1
  file.readlines.each do |line|
    lines[line_number] = line
    line_number += 1
  end
  lines.each_index do |i|  
    line = lines[i]
    puts "line #{i.to_s}: #{line}" if line =~ /bleh/
  end
end


1523
8
задан 28 апреля 2011 в 12:04 Источник Поделиться
Комментарии
1 ответ

File.open( 'grepFile.txt', 'r' ) do |file|
lines = []
line_number = 1
file.readlines.each do |line|
lines[line_number] = line
line_number += 1
end
lines.each_index do |i|
line = lines[i]
puts "line #{i.to_s}: #{line}" if line =~ /bleh/
end
end

файл.readlines.каждый должен быть файл.each_line, который будет делать то же самое (перебрать все строки) без построения массива (и читать весь файл в память) сначала. Также вместо того, чтобы следить за line_number вручную, вы должны просто использовать each_with_index. Хотя на самом деле если вы хотите добавить в конец массива, вы действительно не должны использовать индекс, но использовать << или толкать вместо этого (если вы хотите, чтобы индексы начинаются с 1, Вы можете просто вставить нулевой элемент первого).

Это, как говорится, если все вы хотите, чтобы прочитать файл в массив, вы могли бы просто сделать линии = файл.readlines без каких-либо петлей (или, возможно, [мь] + файл.readlines, так что он продолжает, начиная с 1, но я бы предпочел добавить 1 номеру строки при печати вместо того, чтобы копировать весь массив).

Далее можно использовать методы файл.readlines или файл.по каждому элементу вместо файла.открыть + файл#readlines или файл.открыть + файл#each_line соответственно.

Затем, когда вы перебирайте строки , вы должны использовать each_with_index , а не each_index, так что вам не придется делать линий[я] , чтобы получить значение.

Как последнее примечание, это ненужно вызов to_s на объекте в #{} - Руби делает это автоматически.


Однако в целом подход представляется излишне сложным для меня. Я не понимаю, почему вы должны создать массив на всех. Я бы просто перебрать строки один раз, и вывести их непосредственно. Это помимо того, что намного короче и имеет преимущество в том, что программа работает в за O(1) пространство (при условии, что максимальная длина линии постоянна) и не читать весь файл в память.

File.foreach('grepFile.txt').each_with_index do |line, i|
puts "line #{i}: #{line}" if line =~ /bleh/
end

И конечно, вместо 'grepFile.txt' и /бла/, вы должны использовать аргумент argv[1] и выражения.Новый(из argv[0]), так как нет смысла писать эти ценности.

7
ответ дан 28 апреля 2011 в 01:04 Источник Поделиться