Найти уникальные фамилии из файла .txt в Ruby - PullRequest
0 голосов
/ 18 октября 2019

Мне нужно найти уникальные фамилии из файла .txt, который выглядит следующим образом:

Kent, Mackenna -- ut
    Voluptatem ipsam et at.
Marven, Gardens -- non
    Facere et necessitatibus animi.
McLaughlinn, Matt -- consequatur
    Eveniet temporibus ducimus amet eaque.
Lang, August -- pariatur
    Unde voluptas sit fugit.
Brad, Nick -- et
    Maiores ab officia sed.
Adam, Levine -- error
    Repellendus alias officia amet et perspiciatis.
Learner, York -- nesciunt
    Incidunt et ut necessitatibus porro.
Ortiz, Andrew -- fuga
    Tempore eos et hic.
Lang, Bryant -- et
Laborum perferendis inventore eveniet.

Пока у меня есть:

FNAME = 'example.txt'

# maps for last name in file
def last_name_from_file(file_name)
  last_name = File.readlines(file_name).reject(&:empty?)
  last_name.map do |line|
    line.split.first
  end
end
puts last_name_from_file('example.txt')

, но это дает мне выводкоторый включает текст Lorem и фамилию.

#Kent
#Voluptatem
#Marven
#Facere
#McLaughlinn
#Eveniet
#Lang
#Unde
#Brad
...

Ответы [ 3 ]

1 голос
/ 18 октября 2019

Как я вижу, линии лорема четны, так что вы можете отклонить их.

def last_name_from_file(file_name)
  File.
    readlines(file_name).
    reject.
    with_index(1) { |_, id| id.even? }.
    map { |line| line.split(',').first }.
    uniq
end

Хорошо, как мне получить имя?

Выможет сделать метод следующим образом:

def names(file_name)
  File.
    readlines(file_name).
    reject.
    with_index(1) { |_, id| id.even? }.
    map { |line| line.split(' --').first.split(', ') }.
    map { |ln, fn| { lastname: ln, firstname: fn } }
end

И теперь вы можете вызвать его:

names = names('example.txt')

names
# => [{:lastname=>"Kent", :firstname=>"Mackenna"}, {:lastname=>"Marven", :firstname=>"Gardens"}, {:lastname=>"McLaughlinn", :firstname=>"Matt"}, {:lastname=>"Lang", :firstname=>"August"}, {:lastname=>"Brad", :firstname=>"Nick"}, {:lastname=>"Adam", :firstname=>"Levine"}, {:lastname=>"Learner", :firstname=>"York"}, {:lastname=>"Ortiz", :firstname=>"Andrew"}, {:lastname=>"Lang", :firstname=>"Bryant"}]

names.map { |name| name[:lastname] }
# => ["Kent", "Marven", "McLaughlinn", "Lang", "Brad", "Adam", "Learner", "Ortiz", "Lang"]

names.map { |name| name[:firstname] }
# => ["Mackenna", "Gardens", "Matt", "August", "Nick", "Levine", "York", "Andrew", "Bryant"]
0 голосов
/ 18 октября 2019

Давайте создадим файл.

FName = 'temp.txt'

IO.write(FName,
<<~END
Kent, Mackenna -- ut
    Voluptatem ipsam et at.
Marven, Gardens -- non
    Facere et necessitatibus animi.
McLaughlinn, Matt -- consequatur
    Eveniet temporibus ducimus amet eaque.
Lang, August -- pariatur
    Unde voluptas sit fugit.
Brad, Nick -- et
    Maiores ab officia sed.
Adam, Levine -- error
    Repellendus alias officia amet et perspiciatis.
Learner, York -- nesciunt
    Incidunt et ut necessitatibus porro.
O'Conner-Bolonzo, Andrew -- fuga
    Tempore eos et hic.
Lang, Bryant -- et
Laborum perferendis inventore eveniet.
END
)
  #=> 539

Мы можем извлечь уникальные фамилии, сделав один проход по файлу, читая строку-по-линии;нет необходимости превращать файл в массив, Установить # в_a и String # [] .

Обратите внимание, что, если блок не задан, IO::foreach возвращает перечислитель и, следовательно, можетбыть прикованным, здесь к Enumerable#each_with_object.

Регулярное выражение, используемое String#[] читает, "соответствует одному или нескольким (+) символам в начале строки (\A), которые являются буквамиапострофы или дефисы, сразу после которых ставится запятая ".

0 голосов
/ 18 октября 2019

Что-то похожее на мой ответ со вчерашнего дня:

def last_name_from_file(fname)
  File.open(fname, "r").each_with_object([]).with_index do |(line, o), i|
    o << line.split(',').first if i.even?
  end.uniq
end

puts last_name_from_file('example.txt')

#Kent
#Marven
#McLaughlinn
#...
...