我可以用一些帮助来思考我正在解决的难题。我打算在Ruby中处理它,但可能使用另一种语言,如Javascript / Node。我需要帮助解决问题和设计。
我正在开发一个命令行程序,它读取CSV中的内容,根据参数搜索CSV,然后根据它找到的内容生成输出。
CSV行具有两种格式之一。一个很简单的是餐馆,食品和价格清单:
restaurant ID, price, item label
但对于提供组合餐的餐厅,可以有任意数量的餐馆 价值餐中的物品:
restaurant ID, price, item 1 label, item 2 label, ...
所以我的想法是你可以运行这个程序,使用CSV文件的参数来阅读你要吃的食物,然后输出他们应该去的餐馆,以及它们花费的总价。只要总成本最小化,就可以购买额外的物品。
示例data.csv
1, 4.00, burger
1, 8.00, tofu_log
2, 5.00, burger
2, 6.50, tofu_log
$ foodfinder.rb data.csv burger tofu_log
=> 2, 11.5
与包含多个食品的行类似:
5, 4.00, extreme_fajita
5, 8.00, fancy_european_water
6, 5.00, fancy_european_water
6, 6.00, extreme_fajita, jalapeno_poppers, extra_salsa
$ foodfinder.rb data.csv fancy_european_water extreme_fajita
=> 6, 11.0
由于数据规范化不是一个选项 - 我无法将它们推入数据库 - 我想知道如何考虑如何以有效的方式解析CSV。还有一些行有多个食品我不知道如何存储这些。我猜我想要将行导入哈希,然后以某种方式搜索哈希。任何指导,巫师?
答案 0 :(得分:0)
使用Ruby,我会跳过标准的CSV库,只需加载行,将它们分成最多三个部分,然后将第三个转换为数组。从那时起,您就拥有了所有需要:
records = file.map { |row|
row.split(/,\s?/, 3)
}.map { |arr|
[arr[0].to_i, arr[1].to_f, arr[2].split(/,\s?/)]
}
现在您的记录将是:
[
[5, 4.00, ["extreme_fajita"]],
[5, 8.00, ["fancy_european_water"]],
[6, 5.00, ["fancy_european_water"]],
[6, 6.00, ["extreme_fajita", "jalapeno_poppers", "extra_salsa"]]
]
您可以利用您的知识解决此数据中已完成问题的NP完全问题。
答案 1 :(得分:0)
这些数据很容易用标准CSV library和一点阵列争论来解析:
data = CSV.open('data.csv')
.map { |r| [ r[0], r[1], r[2..-1].map(&:strip) ] }
这会在data
:
data = [
['5', '4.00', ['extreme_fajita']],
['5', '8.00', ['fancy_european_water']],
#...
]
从那里可以轻松构建您需要的任何索引结构。
但是,如果您只想查找'extra_salsa'
行,请使用select
代替map
:
want = CSV.open('x.csv')
.select { |r| r[2..-1].map(&:strip).include?('extra_salsa') }
并清理want
以进行打印,但需要这样做。
每次脚本运行时你都会在整个CSV中旋转,所以你应该在扫描时搜索它,如果你只进行一次搜索,建立中间索引数据结构只是浪费时间每次运行。