Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

218
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda