提问人:Rubin 提问时间:2/16/2023 最后编辑:Holger JustRubin 更新时间:2/17/2023 访问量:74
Ruby 中的解析表
Parsing table in Ruby
问:
出于学习目的,我想解析数据库表并根据类型保存在哈希中,例如表如下所示:
JSON 格式的源表如下所示:
[
{"id": 1 , "type": "Atest", "ip":"10.2.0.1", "port":1234, "description": "xyz"},
{"id": 2 , "type": "Btest", "ip":"10.2.0.2", "port":3000, "description": "xyz"},
{"id": 3 , "type": "subtest", "ip":"10.2.0.3", "port":3001, "description": "xyz"},
{"id": 4 , "type": "Atest", "ip":"10.2.0.4", "port":9999, "description": "xyz"},
{"id": 5 , "type": "subtest", "ip":"10.2.0.5", "port":1235, "description": "xyz"},
{"id": 6 , "type": "Ctest", "ip":"10.2.0.6", "port":1111, "description": "xyz"},
{"id": 7 , "type": "Btest", "ip":"10.2.0.7", "port":2222, "description": "xyz"},
{"id": 8 , "type": "subtest", "ip":"10.2.0.8", "port":3333, "description": "xyz"}
]
我喜欢做的是仅使用类型(Atest 和 Btest)解析此表并保存为哈希值,例如
hash_result ={type: Atest {id: 1 ,description: xyz}, type: Btest {id:2 ,description: xyz}, type: Atest {id: 4 ,description: xyz} , type: Btest {id: 7 ,description: xyz}}
我所想的是像这样的类型有一个开关盒
hash_result={}
when type == "Atest"
hash_result.append(...)
when type == "Btest"
hash_result.append(...)
结果:
hash_result ={type: Atest {id: 1 ,description: xyz}, type: Btest {id:2 ,description: xyz}, type: Atest {id: 4 ,description: xyz} , type: Btest {id: 7 ,description: xyz}}
但是我不确定该怎么做,最后我也想知道在我有一个之后,如何搜索特定的并打印其类型。我将不胜感激任何指导hash_result
[id]
答:
1赞
Jan Vítek
2/17/2023
#1
由于您的结果哈希值不是有效的哈希值,因此我只假设想要的结果,并为您提供如何实现它的大致想法。另外,我不确定您是否更喜欢字符串或符号作为哈希键。由于您的数据示例使用符号,我将坚持使用。
对于过滤,用于根据 ID 使用查找元素Hash#select
Enumerable#find
data = [
{"id": 1 , "type": "Atest", "ip":"10.2.0.1", "port":1234, "description": "xyz"},
{"id": 2 , "type": "Btest", "ip":"10.2.0.2", "port":3000, "description": "xyz"},
{"id": 3 , "type": "subtest", "ip":"10.2.0.3", "port":3001, "description": "xyz"},
{"id": 4 , "type": "Atest", "ip":"10.2.0.4", "port":9999, "description": "xyz"},
{"id": 5 , "type": "subtest", "ip":"10.2.0.5", "port":1235, "description": "xyz"},
{"id": 6 , "type": "Ctest", "ip":"10.2.0.6", "port":1111, "description": "xyz"},
{"id": 7 , "type": "Btest", "ip":"10.2.0.7", "port":2222, "description": "xyz"},
{"id": 8 , "type": "subtest", "ip":"10.2.0.8", "port":3333, "description": "xyz"}
]
filtered = data.select{ |d| %w(Atest Btest).include? d[:type] };
# => [
# {:id=>1, :type=>"Atest", :ip=>"10.2.0.1", :port=>1234, :description=>"xyz"},
# {:id=>2, :type=>"Btest", :ip=>"10.2.0.2", :port=>3000, :description=>"xyz"},
# {:id=>4, :type=>"Atest", :ip=>"10.2.0.4", :port=>9999, :description=>"xyz"},
# {:id=>7, :type=>"Btest", :ip=>"10.2.0.7", :port=>2222, :description=>"xyz"}
# ]
result_hash = filtered.map{ |line| {line[:type].to_sym => line.select{ |key, value| %i(id description).include? key }} }
# => [
# {:Atest=>{:id=>1, :description=>"xyz"}},
# {:Btest=>{:id=>2, :description=>"xyz"}},
# {:Atest=>{:id=>4, :description=>"xyz"}},
# {:Btest=>{:id=>7, :description=>"xyz"}}
# ]
result_hash.find{|element| element.values.first[:id] == 2}
# => {:Btest=>{:id=>2, :description=>"xyz"}}
评论
0赞
Rubin
2/17/2023
代替 .find 方法可以直接使用 .include 方法吗?在过滤?假设 filtered.include?(:id == 2) 类似的东西??
0赞
Jan Vítek
2/17/2023
@Abr 但是,如果您将数据存储在哈希中并使用 ID 作为键,则可以使用最佳解决方案性能。按键搜索哈希值与哈希值的大小无关,使用或类似方法会与哈希值的大小呈线性复杂度。filtered.find{|record| record[:id] == 2}
{1 => {:type=>"Atest", :ip=>"10.2.0.1",...}, 2 => {:type=>"Btest",...}
find
0赞
Rubin
2/17/2023
filtered.find 有效,但我想检查 filtered 中是否存在 id,否则返回 msg like id not found
0赞
Rubin
2/17/2023
好的,我可以做一些事情,例如如果 !filtered.find{|record| record[:id] == 2}.nil?,有没有更好的方法做到这一点
0赞
Rubin
2/17/2023
那么用find方法不合适吗?对于我的情况,您建议我使用 ID 作为我的情况的关键
评论