【问题标题】:How to print rows from a CSV file of index taken from another CSV file如何打印从另一个 CSV 文件获取的索引的 CSV 文件中的行
【发布时间】:2015-12-15 16:31:42
【问题描述】:

我有一个文件Index.csv,其中包含以下数据:

100
200
300
400
500
600
700
800
900
1000

我需要将 CSV 文件 Original.csv 的行打印或保存到新文件 New.csv 中,如 Original.csv 中所述。我该怎么做?

我做不到,所以我将Index.csv的内容复制到一个数组中,并编写了以下代码,但它不起作用:

array = [100,200,300,400,500,600,700,800,900,1000]
CSV.open('New.csv', "wb") do |csv|
    f = File.open('Original.csv', "r")
        f.each_line { |line|
            row = line.split(",")
            for i in 0..array.size
                if array[i]==line
                    csv<<row
                end
            end
    }
end

【问题讨论】:

  • 查看这个问题以了解如何从文件中读取第 n 行 - stackoverflow.com/questions/4014352/…
  • Original.csv 中描述的 CSV 文件 Original.csv 的行”是什么意思?
  • Index.csv 和 Original.csv 能变多大? Index.csv 会一直按升序排列吗?

标签: ruby csv


【解决方案1】:

您的问题中缺少详细信息,例如文件中有多少行,以及索引文件是否已排序。如果没有这些信息并假设最糟糕的、巨大的文件和未排序的索引文件,我会使用类似以下代码的代码:

File.open('new.csv', 'w') do |new_csv|
  File.foreach('index.csv') do |line_num|
    File.open('original.csv', 'r') do |original_csv|
      original_line = ''
      line_num.to_i.times do
        original_line = original_csv.gets
      end
      new_csv.puts original_line
    end
  end
end

假设 index.csv 为:

1
3
5
7
9

和一个 original.csv 的:

row1
row2
row3
row4
row5
row6
row7
row8
row9
row10

运行代码会创建 new.csv:

> cat new.csv
row1
row3
row5
row7
row9

CSV 文件是文本,因此如果我们只关心单独的行,则无需使用 CSV 类来读取或写入它们。

可以进行更改以使用 readlines 并将输入文件和索引添加到结果数组中,但这会导致代码不可扩展。建议的代码将导致重新读取 index.csv 中每一行的 original.csv,但它也会处理任意大小的文件,这在生产环境中非常重要。

例如,如果 index.csv 很小且未排序:

File.open('new.csv', 'w') do |new_csv|
  indexes = File.readlines('index.csv').map(&:to_i).sort
  File.foreach('original.csv').with_index(1) do |original_line, original_lineno|
    new_csv.puts original_line if indexes.include?(original_lineno)
  end
end

这将运行得更快,因为它只遍历 original.csv 一次,但如果 index.csv 变得太大,则会带来潜在的可扩展性问题。

【讨论】:

    【解决方案2】:

    我将向您展示一种无需读取 "Index.csv" 即可打印一行的方法。

    array = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
    i = array.shift
    File.new("Original.csv").each_line.with_index(1) do
      |l, j|
      if j == i
        puts l
        i = array.shift
      end
    end
    

    【讨论】:

    • 我运行了你的代码。它没有在屏幕上显示任何内容。
    • @user5346597 当我尝试它时工作得很好。您的文件是否有 100 行或更多行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多