【问题标题】:use array to iterate and parse other arrays CSV?使用数组迭代和解析其他数组CSV?
【发布时间】:2013-11-25 02:09:07
【问题描述】:

我有一个保存在数组中的人员列表,我想循环一个文件与组织寻找匹配项并保存它们,但它总是出错。我认为我对数组做错了。

这正是我正在做的:

  1. 我有一个名为“personen_fixed.csv”的文件中的人员列表。
  2. 我将该列表保存到一个数组中。
  3. 我有另一个文件,其中也包含人名(“pers2”),还有其他三个有趣的数据列。我将四列保存到数组中。
  4. 我想遍历第一个数组(人员)并搜索与人员列表(“pers2”)的匹配项。
  5. 如果有匹配项,我想保存该行。

我现在得到的是两行数据,其中一行是所有人。请参阅下面的代码。在底部我有一些示例输入数据。

require 'csv'
array_pers1 = []
array_pers2 = []
array_orgaan = []
array_functie = []
array_rol = []

filename_1 = 'personen_fixed.csv'
CSV.foreach(filename_1, :col_sep => ";", :encoding => "windows-1251:utf-8", :return_headers => false) do |row|
  array_pers1 << row[0].to_s
end

filename_2 = 'Functies_fixed.csv'
CSV.foreach(filename_2, :col_sep => ";", :encoding => "windows-1251:utf-8", :return_headers => false) do |row|
  array_pers2 << row[1].to_s
  array_orgaan << row[16].to_s
  array_functie << row[17].to_s
  array_rol << row[18].to_s
end


CSV.open("testrij.csv", "w") do |row|
  row << ["rijnummer","link","ptext","soort_woonhuis"]

  for rij in array_pers1

    for x in 1...4426 do
      if rij === array_pers2["#{x}".to_f]
      pers2 = array_pers2["#{x}".to_f]
      orgaan = array_orgaan["#{x}".to_f]
      functie = array_functie["#{x}".to_f]
      rol = array_rol["#{x}".to_f]
      row << [pers2,orgaan,functie,rol]
      else 
      pers2 = ""
      orgaan = ""
      functie = ""
      rol = ""
      end
    end
  end
end

第一个excel数据的输入数据(excel列名和第一行数据):

person
someonesname

第二个excel文件的输入数据:

person,organizationid,role,organization,function
someonesname,34971,member,americanairways,boardofdirectors

由于数据集中的许多人在不同的组织有多个工作,我想把他们都保存在彼此旁边(我想要的输出):

person,organization(1),function(1),role(1),organization(2),function(2),role(2) (max 5)

【问题讨论】:

  • 提供样本输入数据和预期输出数据。
  • 我有(见下文)。感谢小费锡人
  • 不要将问题的必需部分放在 cmets 中。期望潜在的回答者梳理 cmets 以将问题和所需数据拼凑在一起,这要求很多人试图帮助您。

标签: ruby arrays loops csv


【解决方案1】:

我不明白将 Functies csv 文件中的一行存储在 4 个单独的数组中,然后稍后将它们组合在一起的目的,所以我的回答并没有告诉你为什么你的方法不起作用。相反,我建议另一种我认为更清洁的方法。

从第一个文件构建一个名称数组是可以的。对于第二个文件,我会将每一行存储为一个数组并使用哈希:

data = {
   "name1 => ["name1", "orgaan1", "functie1", "rol1"],
   "name2 => ["name2", "orgaan2", "functie2", "rol2"],
   ...
}

构建它可能看起来像

data = {}
CSV.foreach(filename_2, :col_sep => ";", :encoding => "windows-1251:utf-8", :return_headers => false) do |row|
   name = row[1]
   orgaan = row[16]
   functie = row[17]
   rol = row[18]
   data[name] = [name, orgaan, functie, rol]
end  

然后你会遍历你的第一个数组并保留所有匹配的数组

results = []
for name in array_pers1
  results << data[name] if data.include?(name)
end

另一方面,如果您不想使用哈希并坚持使用数组(可能是因为名称不是唯一的),我仍然会像这样存储它们

data = [
   ["name1", "orgaan1", "functie1", "rol1"],
   ["name2", "orgaan2", "functie2", "rol2"]
]

然后在您的搜索步骤中,您只需像这样进行迭代

results = []
for name in array_pers1
   for row in data
      results << row if row[0] == name
   end
end

【讨论】:

  • 感谢 Keikoku,这看起来更有意义。但是,我将如何自动填充哈希数组? (这个:data = { "name1 =&gt; ["name1", "orgaan1", "functie1", "rol1"], "name2 =&gt; ["name2", "orgaan2", "functie2", "rol2"], ... }
  • 我已对其进行了编辑,以举例说明在解析 filename_2 时如何构建哈希。请注意,哈希方法假定名称是唯一的,因此在这种情况下数组可能会更好。
  • 名字是独一无二的,所以这很完美。再次感谢惠国。如果我只是打印出(放置)结果,它就可以完美地工作,但是当我尝试将其保存到 csv 时仍然出错..CSV.open("testrij.csv", "w") do |csv| csv &lt;&lt; ["rijnummer","link","ptext","soort_woonhuis"] for name in array_pers1 if data.include?(name) csv &lt;&lt; data[name] end end end 对我在这里犯了什么样的愚蠢错误有任何想法? ;)
  • 出了什么问题?发生错误? CSV 文件生成不正确(错误列中的值等)?仍然得到两行数据,其中一行包含所有人?
  • 仍然有两行,其中一行有所有人/“每个单元格的字符数已超出”
猜你喜欢
  • 2012-07-09
  • 1970-01-01
  • 2021-05-26
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
相关资源
最近更新 更多