如何从.txt文件中查找全名的唯一计数,而唯一名称在Ruby中只能找到一次?
这是.txt文件的前10行:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body class="bg-dark">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/"></a>
<button class="navbar-toggler navbar-dark border-0" type="button" data-toggle="collapse" data-target="#nav-content" aria-controls="nav-content" aria-expanded="false" aria-label="Toggle navigation menu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="nav-content">
<ul class="navbar-nav align-items-center">
<li class="nav-item ">
</li>
<li class="nav-item ">
</li>
<li class="nav-item">
</li>
<li class="nav-item">
</li>
<li class="nav-item ">
</li>
</ul>
</div>
</nav>
<main>
<div class="container-fluid h-100">
<div id="map" class="h-100"></div>
</div>
</main>
<footer>
</footer>
</body>
</html>
答案 0 :(得分:1)
如果您只关心独特的商品,那么您想要的是Set。
例如:
names = Set.new(File.readlines('names.txt').map(&:chomp))
将每行的“切碎”版本(减去换行符)放入集合中。
现在您可以将它们全部收回:
names.sort.each do |name|
puts name
end
答案 1 :(得分:1)
我假设这是姓氏,必须唯一。
首先创建文件。
text =<<~END
Smith, Kim
ut Voluptatem ipsam et at.
Marv, Gardens
non Facere et necessitatibus animi.
McLoughlin, Matt
consequatur Eveniet temporibus ducimus amet eaque.
Smith, Jen
pariatur Unde voluptas sit fugit.
Brad, Nick
et Maiores ab officia sed.
END
FName = "test.txt"
File.write(FName, text)
#=> 239
请参见IO::write 1 。现在,我们读取文件并计算唯一姓氏的数量。
require 'set'
File.foreach(FName).with_index.with_object(Set.new) do |(line, idx),set|
set << line[/.+(?=,)/] if idx.even?
end.size
#=> 4
步骤如下。
enum1 = File.foreach(FName)
#=> #<Enumerator: File:foreach("test.txt")>
enum2 = enum1.with_index
#=> #<Enumerator: #<Enumerator: File:foreach("test.txt")>:with_index>
enum3 = enum2.with_object(Set.new)
#=> #<Enumerator: #<Enumerator: #<Enumerator:
# File:foreach("test.txt")>:with_index>:with_object(#<Set: {}>)>
请参见IO::foreach,Enumerator#with_index,Enumerator#with_object和Set::new。请注意,enum2
和enum3
可以被视为复合枚举器。
第一个元素由enum3
生成,传递给块,并为块变量分配值:
(line, idx),set = enum3.next
#=> [["Smith, Kim\n", 0], #<Set: {}>]
line
#=> "Smith, Kim\n"
idx
#=> 0
set
#=> #<Set: {}>
line
,idx
和set
是块变量。将enum3.next
分成三个部分的过程称为array decomposition。有关这项重要技术的完整讨论,请参见this article。
现在可以执行块计算:
idx.even?
#=> true
s = line[/.+(?=,)/]
#=> "Smith"
set << s
#=> #<Set: {"Smith"}>
请参见Integer#even?和Set#<<。在计算s
时,方法Sting#[](的第三种形式)与正则表达式/.+(?=,)/
一起使用,该表达式为“匹配一个或多个字符,后跟一个逗号{{1 }}是正向超前。
第二个元素由(?=,)
生成,传递给块,为块变量分配值并执行块计算:
enum3
自(line, idx),set = enum3.next
#=> [["ut Voluptatem ipsam et at.\n", 1], #<Set: {"Smith"}>]
line
#=> "ut Voluptatem ipsam et at.\n"
idx
#=> 1
set
#=> #<Set: {"Smith"}>
idx.even?
#=> false
起,我们跳过了这一行。 (实际上,包含idx.even? #=> false
的唯一原因是要确定哪些行具有偶数索引。)第三个元素由with_index
生成,传递给块,为块变量分配值,并且块计算为执行:
enum3
依此类推,直到获得:
(line, idx),set = enum3.next
#=> [["Marv, Gardens\n", 2], #<Set: {"Smith"}>]
line
#=> "Marv, Gardens\n"
idx
#=> 2
set
#=> #<Set: {"Smith"}>
idx.even?
#=> true
s = line[/.+(?=,)/]
#=> "Marv"
set << s
#=> #<Set: {"Smith", "Marv"}>
请注意,由于集合包含唯一值,因此在处理arr = File.foreach(FName).with_index.with_object(Set.new) do |(line, idx),set|
set << line[/.+(?=,)/] if idx.even?
end
#=> #<Set: {"Smith", "Marv", "McLoughlin", "Brad"}>
时没有将"Smith"
添加到集合中。现在,我们执行最后一步:
"Smith, Jen"
1即使arr.size
#=> 4
是write
的一种方法,习惯上也以IO
作为接收者来写它(和其他IO
方法)。这是允许的,因为File
是File
的子类,因此继承了后者的方法。 IO
中的两个冒号表示IO::write
是 class方法。相反,write
中的井号表示IO#gets
是 instance方法。
答案 2 :(得分:0)
首先,您必须找出名字而不是名字。然后,您可以根据数组中是否已有该名称将其推入数组。
array.push(name) unless array.include?(name)
然后只对数组进行计数
array.count