Я пытаюсь написать сценарий, который будет проходить через CSV файл в Ruby, который будет создавать многоуровневый неупорядоченный список.
Код, который у меня есть, не отсекает <ul>
в правильных местах. Выход только начинается на новых уровнях.
Вот код Ruby:
require 'csv'
col_data = []
CSV.foreach("primary_NAICS_code.txt") {|row| col_data << row}
begin
file = File.open("primary_NAICS_code.html", "w")
file.write("<ul>\n")
depth = 1
col_data.each do |row|
indentation, (text,*) = row.slice_before(String).to_a
if indentation.length > depth
file.write("<ul>\n")
elsif indentation.length < depth
file.write("</ul>\n")
end
if text.index(/^\d{2}[:]/)
file.write("<li>" +text+ "</li></ul>\n")
else
file.write("<li>" +text+ "</li>\n")
end
depth = indentation.length
end
file.write("</ul>\n")
rescue IOError => e
puts e
ensure
file.close unless file == nil
end
Это результат, который я получаю:
11: Agriculture, Forestry, Fishing and Hunting
111: Crop Production
111110: Soybean Farming
111120: Oilseed (except Soybean) Farming
111130: Dry Pea and Bean Farming
.
.
.
112: Animal Production
112111: Beef Cattle Ranching and Farming
112112: Cattle Feedlots
.
.
.
21: Mining<~~(there should be a </ul> here)
211: Oil and Gas Extraction
211111: Crude Petroleum and Natural Gas Extraction
211112: Natural Gas Liquid Extraction
И файл CSV:
,"11: Agriculture, Forestry, Fishing and Hunting",,
,,"111: Crop Production",
,,,"111110: Soybean Farming"
,,,"111120: Oilseed (except Soybean) Farming"
,,,"111130: Dry Pea and Bean Farming"
,,,"111140: Wheat Farming"
,,,"111150: Corn Farming"
,,,"111160: Rice Farming"
,,,"111191: Oilseed and Grain Combination Farming"
,,,"111199: All Other Grain Farming"
,,,"111211: Potato Farming"
,,,"111219: Other Vegetable (except Potato) and Melon Farming"
,,"112: Animal Production",
,,,"112111: Beef Cattle Ranching and Farming"
,,,"112112: Cattle Feedlots"
,,,"112120: Dairy Cattle and Milk Production"
,,,"112130: Dual-Purpose Cattle Ranching and Farming"
,,,"112210: Hog and Pig Farming"
,,"113: Forestry and Logging",
,,,"113110: Timber Tract Operations"
,,,"113210: Forest Nurseries and Gathering of Forest Products"
,,,"113310: Logging"
,,"114: Fishing, Hunting and Trapping",
,,,"114111: Finfish Fishing"
,,,"114112: Shellfish Fishing"
,,,"114119: Other Marine Fishing"
,,,"114210: Hunting and Trapping"
,,"115: Support Activities for Agriculture and Forestry",
,"21: Mining",,
,,"211: Oil and Gas Extraction",
,,,"211111: Crude Petroleum and Natural Gas Extraction"
,,,"211112: Natural Gas Liquid Extraction"
,,"212: Mining (except Oil and Gas)",
.
.
.
,"54: Professional, Scientific, and Technical Services",,
,,"541: Professional, Scientific, and Technical Services",
,,,"541110: Offices of Lawyers"
require 'csv'
CSV_FILE = 'data.csv'
HTML_FILE = 'data.html'
# helper class for nodes in a tree
class Node < Struct.new(:parent, :text, :children)
def initialize(parent, text)
super
self.children = []
parent.children << self if parent
self
end
def level
root? ? 0 : parent.level + 1
end
def to_html
"".tap do |html|
html << "#{tabs(level)}<li>#{text}" unless root?
html << "#{tabs(level)}<ul>#{children.map(&:to_html).join}</ul>" if children.any?
html << "</li>" unless root?
end
end
private
def root?
parent.nil?
end
def tabs(level)
"\n" + "\t" * level
end
end
# init tree
tree = Node.new(nil, :root)
node = tree
# process csv file
CSV.read(CSV_FILE).map do |row|
levels, (text, _) = row.slice_before(String).to_a
level = levels.size
parent = node if level > node.level
parent = node.parent if level == node.level
parent = node.parent.parent if level < node.level
node = Node.new(parent, text)
end
# write output file
File.open(HTML_FILE, 'w') do |file|
file << "<!DOCTYPE HTML><html><head><title>CSV</title></head><body>"
file << tree.to_html
file << "</body></html>"
end