Ruby:检查CSV多数组中的序列号并取出对应数组更新时间
解决方案:更新CSV中指定序列号的时间值
首先,先放上你当前的代码方便参考:
require 'csv' ######## ## Ask for Serial number ######## serial_number = ask("Product serial number?") serial_number = serial_number.to_s serial_number = serial_number.upcase stamp_date= Time.now old = Time.now.to_i ########## ##Check if file exist in directory ########## if File.exist? ('procedures/Serial.csv') ######### #Check serial number exist in CSV ######### file = File.open("procedures/Serial.csv","r") items = [] while (line1 = file.gets) arr = line1.split(',') items.push ({"Product Number": arr[0],"Time Used": arr[1], "Time in Secs": arr[2]}) end file.close checklist = items.inspect puts checklist repeat = checklist.include?serial_number puts repeat if repeat == true #prompt("Exist") #Thinking I should insert that part of code here to check if the value exist within the csv file. exit else #prompt("Does not exist") ######## #If serial number does not exist, create it within the csv ######## ###### #Append value into the csv ####### CSV.open("procedures/Serial.csv","a+") do |csv| csv << [ serial_number, stamp_date, old] end ############### ## Read the file ############### file = File.open("procedures/Serial.csv","r") items = [] while (line = file.gets) arr = line.split(',') items.push ({"Product Number": arr[0],"Time Used": arr[1], "Time in Secs": arr[2]}) end file.close puts items.inspect end else ####### ##Insert Serial number into file ####### CSV.open("procedures/Serial.csv","wb") do |csv| csv << [ serial_number, stamp_date, old] end ############### ## Read the file ############### file = File.open("procedures/Serial.csv","r") items = [] while (line = file.gets) arr = line.split(',') items.push ({"Product Number": arr[0],"Time Used": arr[1], "Time in Secs": arr[2]}) end file.close puts items.inspect end
你的需求是:当序列号存在时,找到对应的行并更新时间值,而不是直接退出。我会帮你优化代码逻辑,用Ruby的CSV库更优雅地实现这个功能,避免手动split行的潜在问题:
修改后的完整代码
require 'csv' # 获取用户输入的序列号并格式化 serial_number = ask("Product serial number?").to_s.upcase new_stamp_date = Time.now new_time_in_secs = new_stamp_date.to_i csv_path = "procedures/Serial.csv" if File.exist?(csv_path) # 读取CSV所有内容,用CSV库处理更可靠 rows = CSV.read(csv_path) serial_found = false # 遍历每一行,查找匹配的序列号 rows.each do |row| if row[0] == serial_number # 更新该行的时间字段 row[1] = new_stamp_date row[2] = new_time_in_secs serial_found = true break # 找到后停止遍历 end end if serial_found # 把更新后的内容写回CSV CSV.open(csv_path, "wb") do |csv| rows.each { |row| csv << row } end puts "序列号 #{serial_number} 的时间已更新!" else # 序列号不存在,追加新行 CSV.open(csv_path, "a+") do |csv| csv << [serial_number, new_stamp_date, new_time_in_secs] end puts "新序列号 #{serial_number} 已添加!" end else # 文件不存在,创建并写入第一行 CSV.open(csv_path, "wb") do |csv| csv << [serial_number, new_stamp_date, new_time_in_secs] end puts "CSV文件已创建,新序列号 #{serial_number} 已添加!" end # 可选:打印更新后的CSV内容 puts "\n当前CSV内容:" CSV.foreach(csv_path) do |row| puts "产品号: #{row[0]}, 最后使用时间: #{row[1]}, 时间戳: #{row[2]}" end
关键逻辑说明
- 用CSV库替代手动split:Ruby的
CSV.read和CSV.open会自动处理CSV的格式细节(比如逗号转义),比手动split(',')更可靠。 - 查找并更新行:遍历所有行,找到与输入序列号匹配的行后,直接修改该行的第2、3个元素(对应时间和时间戳)。
- 重写CSV文件:因为CSV文件无法直接修改单行,所以找到匹配行后,需要把所有更新后的行重新写入文件。
- 简化流程:把重复的读取/写入逻辑合并,减少冗余代码,让逻辑更清晰。
这样修改后,就能实现你要的:检查序列号存在时,更新对应行的时间值;不存在时添加新行的功能。
内容的提问来源于stack exchange,提问作者KTH
相关产品推荐
相关产品推荐

