【问题标题】:Find the Unique last names from a .txt file in Ruby在 Ruby 中从 .txt 文件中查找唯一姓氏
【发布时间】:2019-10-17 21:52:10
【问题描述】:

我需要从如下所示的 .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
...

【问题讨论】:

  • 所有奇数行都缩进,但最后一行。如果它们总是缩进,请编辑示例;如果它们可能没有缩进,请说出来。请 .edit 以显示给定示例的完整所需结果。每当您给出示例时,请显示所需的结果(作为 Ruby 对象)。

标签: ruby unique


【解决方案1】:

我看到 lorem 线是偶数,所以你可以拒绝它们。

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"]

【讨论】:

  • 好的,我该如何获得名字?
【解决方案2】:

让我们创建文件。

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

我们可以通过单次遍历文件,逐行读取来提取唯一的姓氏;无需将文件 slurp 到数组中。

require 'set'

IO.foreach(FName).each_with_object(Set.new) do |line,set|
   last_name = line[/\A[\p{Alpha}'-]+(?=,)/]
   set << last_name unless last_name.nil?
end.to_a
  #=> ["Kent", "Marven", "McLaughlinn", "Lang", "Brad", "Adam", "Learner",
  #    "O'Conner-Bolonzo"]

请参阅IO::foreachEnumerable#each_with_objectSet::newSet#to_aString#[]

请注意,当没有给定块时,IO::foreach 返回一个枚举器,因此可以链接到 Enumerable#each_with_object

String#[] 使用的正则表达式为:“匹配字符串 (\A) 开头的一个或多个 (+) 字符,它们是字母、撇号或连字符,后跟逗号。”

【讨论】:

    【解决方案3】:

    类似于昨天的my answer

    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
    #...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      相关资源
      最近更新 更多