2

我正在尝试根据两个标准返回特定的单元格值。

逻辑:

If ClientID = 1 and BranchID = 1, puts SurveyID

使用 Ruby 1.9.3,我想基本上查看一个 excel 文件,对于位于ClientIDandBranchID列中的两个特定值,返回列中的相应值SurveyID

这是我到目前为止所拥有的,我在网上搜索时发现的。这似乎很有希望,但没有运气:

require 'csv'

# Load file
csv_fname = 'FS_Email_Test.csv'

# Key is the column to check, value is what to match
search_criteria = { 'ClientID' => '1', 
                   'BranchID' => '1' }

options = { :headers      =>  :first_row,
            :converters   =>  [ :numeric ] }

# Save `matches` and a copy of the `headers`
matches = nil
headers = nil

# Iterate through the `csv` file and locate where
# data matches the options.

CSV.open( csv_fname, "r", options ) do |csv|
  matches = csv.find_all do |row|
    match = true
    search_criteria.keys.each do |key|
      match = match && ( row[key] == search_criteria[key] )
    end
    match
  end
  headers = csv.headers
end

# Once matches are found, we print the results
# for a specific row. The row `row[8]` is
# tied specifically to a notes field.

matches.each do |row|
  row = row[1]
  puts row
end

我知道后面的最后一段代码matches.each do |row|是无效的,但我把它留了下来,希望它对其他人有意义。

我该怎么写puts surveyID if ClientID == 1 & BranchID == 1

4

2 回答 2

3

你确实很亲近。您唯一的错误是将search_criteria哈希值设置为字符串'1'而不是数字。既然你converters: :numeric在那里,那find_all就是比较和1获取。你可以改变它,你就完成了。'1'false

或者,这应该适合你。

关键是线

Hash[row].select { |k,v| search_criteria[k] } == search_criteria

Hash[row]将行转换为哈希而不是数组数组。Select 生成一个新哈希,其中仅包含出现在search_criteria. 然后只需比较两个哈希值,看看它们是否相同。

require 'csv'

# Load file
csv_fname = 'FS_Email_Test.csv'

# Key is the column to check, value is what to match
search_criteria = {
  'ClientID' => 1,
  'BranchID' => 1,
}

options = {
  headers:    :first_row,
  converters: :numeric,
}

# Save `matches` and a copy of the `headers`
matches = nil
headers = nil

# Iterate through the `csv` file and locate where
# data matches the options.

CSV.open(csv_fname, 'r', options) do |csv|
  matches = csv.find_all do |row|
    Hash[row].select { |k,v| search_criteria[k] } == search_criteria
  end
  headers = csv.headers
end

p headers


# Once matches are found, we print the results
# for a specific row. The row `row[8]` is
# tied specifically to a notes field.

matches.each { |row| puts row['surveyID'] }
于 2013-08-21T22:50:50.117 回答
0

可能...

require 'csv'

b_headers = false
client_id_col = 0
branch_id_col = 0
survey_id_col = 0

CSV.open('FS_Email_Test.csv') do |file|
  file.find_all do |row|
    if b_headers == false then

      client_id_col = row.index("ClientID")
      branch_id_col = row.index("BranchID")
      survey_id_col = row.index("SurveyID")
      b_headers = true

      if branch_id_col.nil? || client_id_col.nil? || survey_id_col.nil? then
        puts "Invalid csv file - Missing one of these columns (or no headers):\nClientID\nBranchID\nSurveyID"
        break
      end

    else
      puts row[survey_id_col] if row[branch_id_col] == "1" && row[client_id_col] == "1"
    end

  end
end
于 2013-08-21T22:46:11.017 回答