我有一个包含重复条目的文件。它看起来像
Los Angeles, 6
Los Angeles, 6
New York, 31
New York, 31
New YOrk, 31
.
.
.
现在我想摆脱重复的数据。我尝试做的是使用each_line,看看行是否等于下一行,如果它们相同然后只是跳过,并写入新文件。问题是我应该如何获得该文件的下一行? 或者其他任何建议吗?
答案 0 :(得分:4)
比较下一行是不必要的,因为您可以轻松查看当前行是否与前一行匹配:
file = File.open("filename", "r")
previous_line = nil
file.each_line { |line|
if line == previous_line
# duplicate line; ignore
else
# different; do whatever you want
end
# remember this line so we can compare against it
previous_line = line
}
答案 1 :(得分:3)
如果重复项始终是连续的,那么willglynn的解决方案就可以了。否则,我认为最好的方法是将它们放入哈希值。
unique_list = {}
File.foreach(filename) do |line|
unique_list[line] = 1
end
unique_list.each do |line|
new_file.print line
end
答案 2 :(得分:2)
如果重复的行是连续的,你可以写:
lines = open("file.txt").each_line.chunk(&:downcase).lazy.map { |s, ss| ss.first }
将downcase
替换为您决定哪些字符串等效的函数。
答案 3 :(得分:1)
如果你可以从shell而不是Ruby那里做到这一点,并且你在* nix中工作,它会变得更容易。这是一个名为uniq的* nix工具。
根据您的示例输入,在文件 input.txt :
中Los Angeles, 6
Los Angeles, 6
New York, 31
New York, 31
New YOrk, 31
然后此命令将删除相邻的重复项并将结果打印到标准输出:
$ uniq input.txt
Los Angeles, 6
New York, 31
New YOrk, 31
您会注意到“纽约”第三个例子中的拼写错误导致它不被视为重复。
将结果发送到另一个文件:
$ uniq input.txt >output.txt
$ cat output.txt
Los Angeles, 6
New York, 31
New YOrk, 31
要修改原始文件,您不能将uniq的输出重定向到它 - 您将破坏uniq正在读取的输入。而是使用临时文件:
$ uniq input.txt >input.txt.tmp && cp input.txt.tmp input.txt
$ cat input.txt
Los Angeles, 6
New York, 31
New YOrk, 31
答案 4 :(得分:0)
以@ Anthony的答案为基础。我的想法是:
unique_list = {}
new_file=File.open('file2', "w")
File.foreach('filename') do |line|
unique_list[line] = 1
end
unique_list.each do |key,value|
new_file.puts key
end
每一行都成为散列的键,值为1.键是唯一的,因此重复只会覆盖最后一行。
输出,确保输入字符串末尾没有多余的空格是..
Los Angeles, 6
New York, 31
New YOrk, 31