在哈希数组中搜索匹配的键值对,如果找到匹配则返回true

时间:2016-10-12 11:08:07

标签: ruby-on-rails ruby hash

假设我有这个哈希数组:

[ {"nutrient"=>"protein", "value"=>12, "calories"=>48, "unit"=>"g"},
  {"nutrient"=>"fat", "value"=>5, "calories"=>45, "unit"=>"g"},
  {"nutrient"=>"fibre", "value"=>1, "calories"=>nil, "unit"=>"g"},
  {"nutrient"=>"carbohydrates", "value"=>67, "calories"=>268, "unit"=>"g"},
  {"nutrient"=>"calcium", "value"=>42, "calories"=>nil, "unit"=>"mg"}]

如果(营养价值等于'碳水化合物'它的卡路里等于268)和(如果营养价值等于'蛋白质&#),我怎么能返回布尔值true 39;它的卡路里等于48)

也就是说,简而言之,我想为上面的哈希数组返回true。

5 个答案:

答案 0 :(得分:1)

a.count do |hash|
  (hash['nutrient'] == 'carbohydrates' && hash['calories'] == 268) || (hash['nutrient'] == 'protein' && hash['calories'] == 48)
end == 2

这是做什么的,它会计算集合中的任何元素,通过 EITHER 这个条件:

hash['nutrient'] == 'carbohydrates' && hash['calories'] == 268

或者这个

hash['nutrient'] == 'protein' && hash['calories'] == 48

如果恰好有两场比赛,则返回true

答案 1 :(得分:1)

也许这就是:

public partial class Company : IIdentifiable
    {
        public IEnumerable<Employee> ActiveEmployees
        {
            get
            {
               return Employees.Where(e => !e.User.AccountIsDisabled).Include(x=>x.User).ToList();
            }
        }
    }

或者作为一个不错的发现者方法:

a.any? {|h| h['nutrient'] == 'carbohydrates' && h['calories'] == 268} && 
a.any? {|h| h['nutrient'] == 'proteins'      && h['calories'] == 48}
# => true

输出:

a = [ {"nutrient"=>"protein", "value"=>12, "calories"=>48, "unit"=>"g"}, {"nutrient"=>"fat", "value"=>5, "calories"=>45, "unit"=>"g"}, {"nutrient"=>"fibre", "value"=>1, "calories"=>nil, "unit"=>"g"}, {"nutrient"=>"carbohydrates", "value"=>67, "calories"=>268, "unit"=>"g"}, {"nutrient"=>"calcium", "value"=>42, "calories"=>nil, "unit"=>"mg"}]

def all?(array, *finders)
  finders.all? do |finder|
    array.any? { |hash| finder.all? { |k,v| hash[k] == v } }
  end
end

puts all?(
  a, 
  {'nutrient' => 'protein', 'value' => 12}, 
  {'nutrient' => 'fat', 'calories' => 45}
).inspect

puts all?(
  a, 
  {'nutrient' => 'protein', 'value' => 12},
  {'nutrient' => 'fat', 'calories' => 46}
).inspect

如果未从数组内的任何哈希中找到匹配的哈希,则该方法将返回false。

答案 2 :(得分:1)

假设nutrient值是唯一的,您可以通过以下方式构建calories哈希:

calories = a.each_with_object({}) { |e, h| h[e['nutrient']] = e['calories'] }
#=> {"protein"=>48, "fat"=>45, "fibre"=>nil, "carbohydrates"=>268, "calcium"=>nil}

通过以下方式检查值:

calories['carbohydrates'] == 268 && calories['protein'] == 48
#=> true

答案 3 :(得分:1)

下面,arr是给定的哈希数组(如示例中所示),target是第二个哈希数组,如下所示。

target = [{ "nutrient"=>"carbohydrates", "calories"=>268 },
          { "nutrient"=>"protein", "calories"=>48 }]

对于h中的所有哈希target,我们希望确定arr中的哈希是否与包含h的哈希具有相同的键值对。我们可以用以下方法做到这一点。

<强>代码

def all_match?(arr, target)
  target.all? { |h| arr.any? { |g| g.merge(h) == g } }
end

<强>实施例

对于target的上述值,我们获得

all_match?(arr, target)
  #=> true

现在让我们修改target,以便arr中没有匹配。

target[1]["calories"] = 50
  #=> 50
target
  #=> [{"nutrient"=>"carbohydrates", "calories"=>268},
  #    {"nutrient"=>"protein", "calories"=>50}]
all_match?(arr, target)
  #=> false

<强>解释

在第二个例子中,步骤如下。 target的第一个元素被传递给块,结果是

h = target[0]
  #=> {"nutrient"=>"carbohydrates", "calories"=>268}

并执行块计算。

arr.any? { |g| g.merge(h) == g }
  #=> true

碰巧,匹配的哈希是

g = arr[3]
  #=>{"nutrient"=>"carbohydrates", "value"=>67, "calories"=>268, "unit"=>"g"},
g.merge(h) == g
  #=> true

我所做的是将h合并到arr中的每个哈希中,直到找到一个g,其返回g未被合并更改。要实现这一点,h中的所有键值对都必须出现在g

由于返回了trueall?会将target的第二个元素传递给块,然后执行块计算。

h = target[1]
  #=> {"nutrient"=>"protein", "calories"=>50} 
arr.any? { |g| g.merge(h) == g }
  #=> false  

找到false后,all?会返回false

答案 4 :(得分:-1)

a=[ {"nutrient"=>"protein", "value"=>12, "calories"=>48, "unit"=>"g"}, {"nutrient"=>"fat", "value"=>5, "calories"=>45, "unit"=>"g"}, {"nutrient"=>"fibre", "value"=>1, "calories"=>nil, "unit"=>"g"}, {"nutrient"=>"carbohydrates", "value"=>67, "calories"=>268, "unit"=>"g"}, {"nutrient"=>"calcium", "value"=>42, "calories"=>nil, "unit"=>"mg"}]

    a.map! do |value|
      if value["nutrient"].eql?'protein' and value["calories"].eql?268
        true
      elsif  value["nutrient"].eql?'protein' and value["calories"].eql?48
        true
      else
        false
      end
    end

puts a.inspect