I suggest you write it as follows.
class Fact
def initialize (fact)
@fact = fact
end
def fact
@fact[:fact]
end
def is_real?
@fact[:real]
end
def speaker
@fact[:speaker]
end
end
Create some instances.
facts = [["grass is green", true, "Bob"], ["bears are orange", false, "Sue"],
["cats say 'woof'", false, "Bob"], ["dogs are delightful", true, "Hal"]].
map { |f,t,s| Fact.new(fact: f, real: t, speaker: s) }
#=> [#<Fact:0x007fd363e4bcc0 @fact=
# {:fact=>"grass is green", :real=>true, :speaker=>"Bob"}>,
# #<Fact:0x007fd363e4bc20 @fact=
# {:fact=>"bears are orange", :real=>false, :speaker=>"Sue"}>,
# #<Fact:0x007fd363e4bb80 @fact=
# {:fact=>"cats say 'woof'", :real=>false, :speaker=>"Bob"}>,
# #<Fact:0x007fd363e4bae0 @fact=
# {:fact=>"dogs are delightful", :real=>true, :speaker=>"Sue"}>
# ]
Partition facts into passing_facts and alternative_facts.
passing_facts, alternative_facts = facts.partition(&:is_real?)
#=> [[#<Fact:0x007fd363e4bcc0 @fact=
# {:fact=>"grass is green", :real=>true, :speaker=>"Bob"}>,
# #<Fact:0x007fd363e4bae0 @fact=
# {:fact=>"dogs are delightful", :real=>true, :speaker=>"Hal"}>
# ],
# [#<Fact:0x007fd363e4bc20 @fact=
# {:fact=>"bears are orange", :real=>false, :speaker=>"Sue"}>,
# #<Fact:0x007fd363e4bb80 @fact=
# {:fact=>"cats say 'woof'", :real=>false, :speaker=>"Bob"}>
# ]
# ]
passing_facts
#=> [#<Fact:0x007fd363e4bcc0 @fact=
# {:fact=>"grass is green", :real=>true, :speaker=>"Bob"}>,
# #<Fact:0x007fd363e4bae0 @fact=
# {:fact=>"dogs are delightful", :real=>true, :speaker=>"Hal"}>
# ]
alternative_facts
# [#<Fact:0x007fd363e4bc20 @fact=
# {:fact=>"bears are orange", :real=>false, :speaker=>"Sue"}>,
# #<Fact:0x007fd363e4bb80 @fact=
# {:fact=>"cats say 'woof'", :real=>false, :speaker=>"Bob"}>
# ]
Compile list of speakers for alternative_facts.
alternative_speakers = alternative_facts.map { |f| f.speaker }
#=> ["Sue", "Bob"]
Reject elements of passing_facts for which the value of the key :speaker is a member of alternative_speakers, then map those remaining to the name of the fact.
passing_facts.reject { |f| alternative_speakers.include?(f.speaker) }.
map { |f| f.fact }
#=> ["dogs are delightful"]
Note
passing_facts.reject { |f| alternative_speakers.include?(f.speaker) }
#=> [#<Fact:0x007fd364a38e70 @fact=
# {:fact=>"dogs are delightful", :real=>true, :speaker=>"Hal"}>
# ]
If there are large number of "facts", efficiency could be improved by adding require 'set' and tack .to_set to the end of the expression that computes facts.