Algunos métodos de Ruby que deberías conocer, map, pluck, tap, entre otros, ¿te los presento?


Meet Fant!Vamos a hablar de algunos métodos interesantes que me he encontrado y me gustaría compartir. El primero que quería presentarte es el Enumerable Methods: map de Ruby. Es uno de los métodos, que cuando lo vi me pareció genial, fíjate en este primer paso:

1.9.3p327 :027 > (1..5).map(&:odd?)
=> [true, false, true, false, true]

En este primer caso lo que le estamos diciendo es, que de los número que te estoy dando del 1 al 5, me vas a dar un nuevo array, pero que sean impares y me dices si son o no, es decir, que odd? me va a devolver un true o false si cumple si es impar. Este caso es muy curioso ya que map me permite determinan dentro, lo que queremos que devuelva como nuevo array final. En este segundo caso hace lo mismo pero con el select, que nos permite definir una nueva salida de datos en la que únicamente nos devuelva aquellos que sean true. Te vas dando cuenta de lo interesante del método verdad?

1.9.3p327 :028 > (1..5).map(&:odd?).select { |e| e == true}
=> [true, true, true]

Si necesitamos saber cuantos hay dentro del array que cumplen la condición de ser impar, con count lo tenemos resulto

1.9.3p327 :029 > (1..5).map(&:odd?).select { |e| e == true}.count
=> 3

También lo podemos llevar al campo de comparaciones arrays completos, por ejemplo imagina que tenemos un array que dispone de ids de aplicaciones que tienen un permiso para el usuario actual y queremos comprarlo con las aplicaciones que vamos a obtener de la base de datos, en donde applications es una relación has_many :applications, through: :user_applications, source: :application, :conditions => proc { {permission: self.permissions} }, order: ‘user_applications.position’ y in_tab es un scope :in_tab,  lambda { |tab|  where(tab: tab) }. El final lo que estamos comparando sin dos arrays de ids.

if current_app_ids == applications.in_tab(tab).map(&:id)
    app = user_applications.in_tab(tab).find_by_application_id(application_id)
    app.insert_at(new_index) unless app.nil?
end

Fíjate ene este caso:

users = User.all

users.map(&:email)

tenemos como resultado de users = User.all todos los usuarios con todos sus campos y el en el segundo paso obtenemos únicamente los emal que es el campo que me interesa, users.map(&:email).

Ahora lo hacemos en dos pasos primero seleccionamos únicamente el campo email y después saca en un nuevo array los email:

emails = User.select(:email)

emails.map(&:email)

1.9.3p327 :321 > u = User.select(:name)

User Load (0.3ms) SELECT name FROM “users”
=> [#<User name: “admin”>, #<User name: “Carlos”>]
1.9.3p327 :322 > u.map(&:name)
=> [“admin”, “Carlos”]

Pluck es otro de esos métodos interesantes, está diseñado para devolver una colección de valores mediante la realización de una única columna como consulta directa de un SELECT SQL. Como ejemplo de uso de pluck, lo metemos un un único paso y si necesitamos condicionar la salida, actuamos con where:

User.pluck(:email)

User.where(active:true).pluck(:email)

Si necesitamos cambiar el array de números a string lo haríamos con num.to_s como bloque o como map(&:to_s)

1.9.3p327 :011 > (1..5).map { |num| num.to_s }
=> [“1”, “2”, “3”, “4”, “5”]

1.9.3p327 :012 > (1..5).map(&:to_s)
=> [“1”, “2”, “3”, “4”, “5”]
1.9.3p327 :013 >

Otros métodos interesantes de Enumerable Methods a comentar son first, last, each, max, min

1.9.3p327 :030 > [“a”, “b”, “c”].first
=> “a”

1.9.3p327 :087 > [“a”, “b”, “c”].first(2)
=> [“a”, “b”]

1.9.3p327 :031 > [“a”, “b”, “c”].last
=> “c”

1.9.3p327 :038 > [“a”, “b”, “c”].each { |j| puts “el elemento es: #{j}” }
el elemento es: a
el elemento es: b
el elemento es: c
=> [“a”, “b”, “c”]

1.9.3p327 :041 > [“a”, “b”, “c”].min
=> “a”
1.9.3p327 :042 > [“a”, “b”, “c”].max
=> “c”
1.9.3p327 :043 > [45, 5, 78, 90, 1].max
=> 90
1.9.3p327 :044 > [45, 5, 78, 90, 1].min
=> 1

1.9.3p327 :048 > [“aaaaaaaaaa”, “bbbb”, “ccccc”].min.size
=> 10

Vemos algunos otros interesantes como inject, select y reject

1.9.3p327 :323 > [1,2,3].map { |x| x + 1 }.tap { |y| p y }.inject(:+)
[2, 3, 4]
=> 9

1.9.3p327 :324 > [1,2,3,4,5,6,7,8,9,10].inject{|sum,e|sum += e}
=> 55

1.9.3p327 :325 > [1,2,3,4,5,6,7,8,9,10].select{|el| el%2==0}

=> [2, 4, 6, 8, 10]
1.9.3p327 :326 > [1,2,3,4,5,6,7,8,9,10].reject{|e| e==2 || e==8}
=> [1, 3, 4, 5, 6, 7, 9, 10]
1

Para terminar veamos tap

   def sample_method

        e = Employee.new

        e.name = “Hi all”

        e.save 

        e

  end

En este primer caso nos devuelve el objeto creado “e”  

def sample_method
        e = Employee.new
        e.name = “Hi all”
        e.tap { |emp| emp.save }
end

Para el segundo caso, lo que obtenemos es, que devuelve el objeto creado dentro del bloque de “e.tab {…}” marcado en rojo

def sample_method
      Employee.new.tap do |e|
         e.name = “Hi all”
         e.save
     end
end

Este último paso, está mucho más claro, el uso de tap, ya que dentro del bloque Employee.new.tap do |e| ….end hacemos las acciones, pero atención, no devuelve la última línea del bloque, en este caso, devuelve el nuevo objeto creado con Employee.new.tap do |e|. Prueba e investiga es muy interesante.

En otros post seguiré comentando métodos que sean interesantes utilizar para poder ahorrar tiempo y limpieza de código.

2 comentarios en “Algunos métodos de Ruby que deberías conocer, map, pluck, tap, entre otros, ¿te los presento?

    • carlossanchezperez dijo:

      Gracias Fernando por la pista, muy bueno, le he echado un vistazo a:

      [3,5].all? {|x| x.odd?}
      => true
      [2,4,6,8,5].all? {|x| x > 100}
      => false
      [2,4,6,8,7].one? {|x| x.odd?}
      => true
      [2,4,6,8,7].none? {|x| x.odd?}
      => false
      [1, 2, 3].all?
      => true
      [1, 2, 3, nil].all?
      => false

      …………podría dar para un post, no?

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s