0

I have this array:

@import = [{"User"=>[9], "Project"=>false, "Task"=>false, "Date"=>"2017-08-11", "Time (Hours)"=>2.0, "Comment"=>"Test 11"}, 1]

How do I find the keys which has the false value in the above array?

Gerry
  • 10,337
  • 3
  • 31
  • 40
Archie123
  • 105
  • 2
  • 13
  • Is the array structure always the same (first element is the hash, and other elements don't need to be tested) ? – MrYoshiji Aug 07 '17 at 14:28
  • Yes the array structure is going to be like this or like this @import_response is [{:user_id=>9, :timesheet_project_id=>4, :timesheet_task_id=>87, :date=>"2017-08-13", :time_spent=>2.0, :comment=>"Test 13"}, {:user_id=>9, :timesheet_project_id=>4, :timesheet_task_id=>87, :date=>"2017-08-13", :time_spent=>2.0, :comment=>"Test 13"}, {:user_id=>9, :timesheet_project_id=>4, :timesheet_task_id=>87, :date=>"2017-08-13", :time_spent=>2.0, :comment=>"Test 13"}, {:user_id=>9, :timesheet_project_id=>4, :timesheet_task_id=>87, :date=>"2017-08-13", :time_spent=>2.0, :comment=>"Test 13"}] – Archie123 Aug 07 '17 at 14:39
  • @Archie123 so by "yes" you mean that it is not always like that? Your second array looks totally different. – Stefan Aug 07 '17 at 14:43
  • yes it is not always going to be like that .. it will contain the hash of entries which need to be inserted or the single hash with the error line number as in the first case. – Archie123 Aug 07 '17 at 14:48

3 Answers3

3

You can use Hash#select:

hash = {"User"=>[9], "Project"=>false, "Task"=>false, "Date"=>"2017-08-11", "Time (Hours)"=>2.0, "Comment"=>"Test 11"}
hash.select { |k,v| v == false }
# => {"Project"=>false, "Task"=>false}

Other useful Hash methods: Ruby: Easiest Way to Filter Hash Keys?

MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • This will give as a result a hash, but not "the keys which has the false value". – marzapower Aug 07 '17 at 14:32
  • @marzapower You could add `.keys` at the end to get them, i.e.: `hash.select { |k,v| v == false }.keys`. – Gerry Aug 07 '17 at 14:33
  • Also, since `k` is not used, it could be replaced with `_ ` (i.e. `hash.select { |_,v| v == false }`). – Gerry Aug 07 '17 at 14:35
  • Yes, I know, but it's preferable to have answers that are "correct". – marzapower Aug 08 '17 at 14:02
  • @marzapower Stackoverflow community is here to help you find the way to solve your problems, not to fix them for you. "Give a man a fish and you will feed him for a day. Teach him how to fish and you will feed him for a lifetime". – MrYoshiji Aug 08 '17 at 14:05
2

You can use each_with_object

@import.first.each_with_object([]) do |(key, value), accu|
  accu << key if value == false
end

or:

@import.first.select { |_key , value| value == false }.keys
Pascal
  • 8,464
  • 1
  • 20
  • 31
  • @Gerry fixed the `NoMethodError`. And yes, the second variant is pretty much the same as @MrYoshiji (except for the `keys` which you mentioned in the comments) – Pascal Aug 07 '17 at 14:39
  • Yep, i noticed, so i deleted my comment :) – Gerry Aug 07 '17 at 14:39
1

Assuming that the structure of the array is always the same, you could do this:

@import.first.keys.select { |key| @import.first[key] == false }
#=> ["Project", "Task"]
Gerry
  • 10,337
  • 3
  • 31
  • 40