根据列表元素查找元素字典

时间:2019-08-13 14:49:08

标签: ruby

我有一个类似的字典:

{"services"=>["foo", "bar", "test"], "foo_limit_max"=>2, "test_limit_min"=>6}

我想从services列表中提取所有在servicename_limit_*之后有键的那些服务

我尝试了以下dict['services'].select { |x| dict.key?(/#{x}_limit_*/)},但未返回任何内容。

预期输出为['foo', 'test']

3 个答案:

答案 0 :(得分:2)

我会这样处理

dict['services'] & dict.keys.flat_map {|k| k.scan(/\w+(?=_limit_)/)}

在这里,我们在Array#&和与给定模式匹配的键之间使用dict['services'](交集)。

dict.keys.flat_map {|k| k.scan(/\w+(?=_limit_)/)}
#=> ["foo", "test"]

@SergioTulentsev建议的另一个(效果更好)是

dict['services'].select {|s| dict.any? {|k,_| k.start_with?(s)}}

Benchmarks Provided By @SergioTulentsev

# >> Warming up --------------------------------------
# >>               sergio    54.608k i/100ms
# >>              aleksei     6.257k i/100ms
# >>                 cary    40.951k i/100ms
# >>        engineersmnky    16.093k i/100ms
# >> Calculating -------------------------------------
# >>               sergio    663.692k (± 3.5%) i/s -      3.331M in   5.025472s
# >>              aleksei     64.006k (± 2.9%) i/s -    325.364k in   5.087717s
# >>                 cary    472.838k (± 3.1%) i/s -      2.375M in   5.028133s
# >>        engineersmnky    167.907k (± 2.0%) i/s -    852.929k in   5.081762s
# >>
# >> Comparison:
# >>               sergio:   663691.8 i/s
# >>                 cary:   472838.2 i/s - 1.40x  slower
# >>        engineersmnky:   167906.6 i/s - 3.95x  slower
# >>              aleksei:    64005.5 i/s - 10.37x  slower
# >>

答案 1 :(得分:1)

input['services'].reject do |x|
  input.keys.grep(/\A#{x}_limit_/).empty?
end
#⇒ ["foo", "test"]

答案 2 :(得分:1)

h = {"services"=>["foo", "bar", "test"], "foo_limit_max"=>2, "test_limit_min"=>6}

h["services"] & h.keys.map { |k| k[/.+?(?=_limit_)/] }
  #=> ["foo", "test"]

注意:

h.keys.map { |k| k[/.+?(?=_limit_)/] }
  #=> [nil, "foo", "test"]

请参见Array#&,其中包括句子“顺序是从原始数组中保留的。”。