0
input = [ {"name" => "adam",  "nick" => ["kuruvi", "cali"] },
          {"name" => "eve",   "nick" => ["cali"]           },
          {"name" => "enoch", "nick" => []                 },    
          {"name" => "ebe",   "nick" => ["test", "wrong"]  },
          {"name" => "fred",  "nick" => ["da"]             } ]

I want to select hashes which contains "da" & "cali" in "nick".

input.select do |d|
  d["nick"].include?("cali")
end

gives

[{"name"=>"adam", "nick"=>["kuruvi", "cali"]},
 {"name"=>"eve", "nick"=>["cali"]}]

How can we include two parameters in check. Eg: include?("cali","da") so that my result will be

 [{"name"=>"adam", "nick"=>["kuruvi", "cali"]},
  {"name"=>"eve", "nick"=>["cali"]},
  {"name" => "fred",  "nick" => ["da"]}]

Tried this

 i = ["da","cali"]
 input.select do |d|
   d["nick"].all? { |v| i.include? v }
 end

=> [{"name" => "adam",  "nick" => ["kuruvi", "cali"]},
    {"name" => "eve",   "nick" => ["cali"]},
    {"name" => "enoch", "nick" => []},
    {"name" => "fred",  "nick" => ["da"]}]

(but this returns hashes with "nick"=[] also)

0

3 Answers 3

2

On the basis of your desired result you are referring to "or", not "and". The following uses the method Array#&.

input.reject { |h| (h["nick"] & ["cali", "da"]).empty? }
  #=> [{"name"=>"adam", "nick"=>["kuruvi", "cali"]},
  #    {"name"=>"eve", "nick"=>["cali"]},
  #    {"name"=>"fred", "nick"=>["da"]}] 
Sign up to request clarification or add additional context in comments.

Comments

1

You need to do two different include? tests:

l = d['nick']
l.include?('da') && l.include?('cali')

You could also try:

(d['nick'] & %w[ da cali ]).length == 2

Or if you want you could write your own method to test for overlap like that, perhaps even patching it into Array as include_all?

3 Comments

Tried this:: i = ["da","cali"] input.select do |d| d["nick"].all? { |v| i.include? v } end
the above returns {"name" => "enoch", "nick" => []} also..where "nick" is []
The all? call isn't in the right spot there. That won't work.
0

Instead of using all?, you can use any? to achieve the desired result.

input.select do |d|
  d["nick"].any? { |h| ['cali','da'].include?(h) }
end

This returns

[{"name"=>"adam", "nick"=>["kuruvi", "cali"]}, 
 {"name"=>"eve",  "nick"=>["cali"]}, 
 {"name"=>"fred", "nick"=>["da"]}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.