Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

219
Views
Ruby on Rail bitwise operators (&) for the complex types arrays

I am trying to use the bitwise operator (&) for the arrays in the Ruby on Rails

When I have the simple type arrays

one = ["one", "two", "three"]
two = ["one", "two", "three"]

And have this code

puts (one & two)

I get the output:

one two three

However, when I am having the complex types arrays

list1 = [Someitem.new("1", "item1"),Someitem.new("2", "item2"),Someitem.new("3", "item3"),Someitem.new("4", "item4")]
list2 = [Someitem.new("1", "item1"),Someitem.new("2", "item2"),Someitem.new("3", "item3"),Someitem.new("4", "item4")]

For the class where I do override the to_s method

class Someitem
    attr_accessor :item_id, :item_name
    def initialize(item_id, item_name)
      self.item_id = item_id;
      self.item_name= item_name;
    end
    
   def to_s
     item_name
   end  
end

And have this code

puts (list1 & list2)

I get nothing in the output

What can I do to get the output for the complex types arrays using the bitwise & operator to find common values within those two lists?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

The Ruby 3.0 docs for Array#& say:

[...] items are compared using eql?

The Ruby 2.7 docs for Array#& say:

It compares elements using their hash and eql? methods for efficiency

So in order to get this working for your class, you have to implement / override eql? and (for 2.7 compatibility) hash according to the docs. There are many ways to do this, here's a simple approach:

class Someitem

  # ...

  def hash
    [item_id, item_name].hash
  end

  def eql?(other)
    return false unless other.is_a?(Someitem)

    [item_id, item_name] == [other.item_id, other.item_name]
  end
  alias == eql?  # <- this isn't needed but convenient
end

The above implementation uses item_id and item_name to calculate the object's hash and to determine object equality:

Someitem.new("1", "item1").hash == Someitem.new("1", "item1").hash
#=> true

Someitem.new("1", "item1").eql? Someitem.new("1", "item1")
#=> true

[Someitem.new("1", "item1")] & [Someitem.new("1", "item1")]
#=> [#<Someitem:0x00007f8ff505d228 @item_id="1", @item_name="item1">]
over 4 years ago · Santiago Trujillo Report

0

Firstly, while Integer#& is the bit-wise AND operator, Array#& is the set intersection operator (though I find the term "set" grating because an array is not a set).

You appear to be assuming that

Someitem.new("1", "item1") == Someitem.new("1", "item1") #=> true

However, the two instances are not the same object, so in fact:

Someitem.new("1", "item1") == Someitem.new("1", "item1") #=> false

Recalling that every object has a unique object_id, consider the following:

list1.map(&:object_id)
  #=> [1520, 1540, 1560, 1580]
list2.map(&:object_id)
  #=> [1600, 1620, 1640, 1660]

Since [1520, 1540, 1560, 1580] and [1600, 1620, 1640, 1660] have no common elements we see that their intersection is empty:

list1.map(&:object_id) & list2.map(&:object_id)
  #=> [1520, 1540, 1560, 1580] & [1600, 1620, 1640, 1660]
  #=> []
over 4 years ago · Santiago Trujillo Report

0

When arrays are involved, & is actually the intersection, it's not the bitwise AND.

To return the common elements between your lists, the #hash method is called.

For your first example, calling "one".hash returns the same value all the time, which is actually a hit.

"one".hash # => 103347303317675750
"one".hash # => 103347303317675750

In the second example you work with different instances, which, of course don't match.

Someitem.new("1", "item1").hash # => a_value
Someitem.new("1", "item1").hash # => another_value

If you pass the same instance to both arrays, it will match.

 a = Someitem.new("1", "item1")
 a.hash # => a_value
 a.hash # => same_value_as_above

 list1 = [a]
 list2 = [a]
 list1 & list2 # => [a]
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!