2015-01-16 2 views
0

У меня есть несколько текстовых файлов, и мне нужно, чтобы быть в состоянии разобрать через них с тремя различными выходами:Разбирает через текстовые файлы и выводить их в новом формате

  • Выход 1 - отсортировано по полу (женщин перед мужчинами), затем по имени возрастает.
  • Выход 2 - отсортировано по дате рождения, по возрастанию.
  • Выход 3 - отсортировано по дате, убыванию.

Вот пример всех трех текстовых файлов:

pipe.txt:

Smith | Steve | D | M | Red | 3-3-1985 
Bonk | Radek | S | M | Green | 6-3-1978 
Bouillon | Francis | G | M | Blue | 6-3-1975 

comma.txt:

Abercrombie, Neil, Male, Tan, 2/13/1943 
Bishop, Timothy, Male, Yellow, 4/23/1967 
Kelly, Sue, Female, Pink, 7/12/1959 

space.txt:

Kournikova Anna F F 6-3-1975 Red 
Hingis Martina M F 4-2-1979 Green 
Seles Monica H F 12-2-1973 Black 

я был в состоянии получить pipe.txt в алфавитном порядке, написав это:

pipe = File.open('pipe.txt', 'r') 
alpha = pipe.sort { |a, b| a <=> b } 
puts alpha 

У меня не было никакой удачи выяснить что-нибудь еще. Любая помощь будет оценена по достоинству.

ответ

0

Во-первых, ваш образец кода может работать, но на это не на что вы рассчитываете положиться.

Я бы написать

pipe = File.open('pipe.txt', 'r') 
alpha = pipe.sort { |a, b| a <=> b } 
puts alpha 

как:

alpha = File.readlines('pipe.txt').sort 

Разница заключается в том, что с помощью open и сортировки ручки оставляет ручка открыть файл. Висячие файловые дескрипторы могут потреблять все доступные дескрипторы системы, что создает проблемы при выполнении длительных задач, поэтому привыкайте к методам или конструкциям, которые автоматически закрывают файлы, когда они будут выполнены, или убедитесь, что вы явно закрываете файл , Использование readlines автоматически возвращает массив строк И закрывает файл, когда он закончил чтение. Затем этот массив передается в sort.

A bare sort будет автоматически использовать тот же блок, что и { |a, b| a <=> b }, так что это лишний и не нужен.

Ваш код сортировки по всей строке, но это не совсем то, что вы хотите. Вместо этого вы ДОЛЖНЫ разбить строки на столбцы компонентов, а затем сортировать их.Рассмотрим это:

ary = [ 
    'a b', 
    'a b' 
].sort 

ary # => ["a b", "a b"] 

На поверхности кажется, как 'a b' будет такой же, как 'a b' или после него, но, поскольку ' ' имеет более низкое значение ASCII, чем b, 'a b' заканчивает сопоставляя до того 'a b':

Глядя на фактические значения:

'a b'.chars.map(&:ord) # => [97, 32, 98] 
'a b'.chars.map(&:ord) # => [97, 32, 32, 98] 

Итак, поэтому мы хотим разделить линии на свои значения, чтобы отрицать эффект разделителей.

Двигаясь дальше, разделение линий не обязательно, что вы хотите сделать в «универсальном» методе, хотя вы могли бы. И я не собираюсь писать все это для вас, но я укажу путь.

«comma.txt» может быть проанализирован с использованием встроенной библиотеки CSV. «CSV» означает «Comma Separated Values». В документации уже есть пример, показывающий, как анализировать строки из файла или из строки. Я использую строчную версию, но вы хотите изменить ее, чтобы использовать версию файла. В качестве исходного теста, это показывает, что мы можем сортировать подмассивы и получить желаемые результаты:

text = 'a,b,c 
a,a,b 
a,a,a 
' 

require 'csv' 

ary = [] 
CSV.parse(text) do |row| 
    ary << row 
end 

ary.sort 
# => [["a", "a", "a"], ["a", "a", "b"], ["a", "b", "c"]] 

Теперь можно просто разбить строки в поля компонентов и вещи должны работать:

text = 'Abercrombie, Neil, Male, Tan, 2/13/1943 
Bishop, Timothy, Male, Yellow, 4/23/1967 
Kelly, Sue, Female, Pink, 7/12/1959 
' 

require 'csv' 

ary = [] 
CSV.parse(text) do |row| 
    ary << row 
end 

ary.sort 
# => [["Abercrombie", " Neil", " Male", " Tan", " 2/13/1943"], 
#  ["Bishop", " Timothy", " Male", " Yellow", " 4/23/1967"], 
#  ["Kelly", " Sue", " Female", " Pink", " 7/12/1959"]] 

Обратите внимание, что поля сохраняют свои ведущие пробелы. Вы можете использовать strip в отдельных полях, чтобы удалить начальные и конечные пробелы, или map(&:strip). Вам решать, как это сделать.

Работа с pipes.txt почти то же самое, он просто принимает говорить CSV, как интерпретировать столбцы:

text = 'Smith | Steve | D | M | Red | 3-3-1985 
Bonk | Radek | S | M | Green | 6-3-1978 
Bouillon | Francis | G | M | Blue | 6-3-1975 
' 

require 'csv' 

ary = [] 
CSV.parse(text, col_sep: '|') do |row| 
    ary << row 
end 

ary.sort 
# => [["Bonk ", " Radek ", " S ", " M ", " Green ", " 6-3-1978"], 
#  ["Bouillon ", " Francis ", " G ", " M ", " Blue ", " 6-3-1975"], 
#  ["Smith ", " Steve ", " D ", " M ", " Red ", " 3-3-1985"]] 

Опять же, пробелы сохраняются, только теперь они завершающие пробелы. И, опять же, вы можете понять, как с ними справиться.

Работа с text.txt, вероятно, самым простым:

text = 'Kournikova Anna F F 6-3-1975 Red 
Hingis Martina M F 4-2-1979 Green 
Seles Monica H F 12-2-1973 Black 
' 

ary = text.split("\n").map { |row| 
    row.split 
} 
puts ary.map{ |r| r.join(',') } 

# >> Kournikova,Anna,F,F,6-3-1975,Red 
# >> Hingis,Martina,M,F,4-2-1979,Green 
# >> Seles,Monica,H,F,12-2-1973,Black 

ary.sort 
# => [["Hingis", "Martina", "M", "F", "4-2-1979", "Green"], 
#  ["Kournikova", "Anna", "F", "F", "6-3-1975", "Red"], 
#  ["Seles", "Monica", "H", "F", "12-2-1973", "Black"]] 
0

Это проще всего пойти в формате CSV, и пусть библиотеку делать разбор из данных в отдельные области.

Вот пример скрипта, который показывает ваши 3 порядок сортировки

require 'csv' 
require 'date' 

data = CSV.parse(DATA) 

SurnameIndex = 0 
GenderIndex = 2 
DateIndex = 4 

puts "By gender then surname: %s" % data.sort_by.sort_by { |object| [ object[GenderIndex], object[SurnameIndex] ] }.inspect 
puts "By birth date: %s" % data.sort_by.sort_by { |object| Date.strptime(object[DateIndex], '%m/%d/%Y') }.inspect 
puts "By surname descending: %s" % data.sort_by.sort { |a, b| b[SurnameIndex] <=> a[SurnameIndex] }.inspect 

__END__ 
Abercrombie,Neil,Male,Tan,2/13/1943 
Bishop,Timothy,Male,Yellow,4/23/1967 
Kelly,Sue,Female,Pink,7/12/1959 

Обратите внимание на последний сорт имеет в a и b объекты обращенных, чтобы получить обратный порядок вам требуется

Смежные вопросы