Yield in a set for exclusion in an array

I found the following code here to eliminate duplicate entries in an array:

require 'set'

class Array
  def uniq_by
    seen = Set.new
    select{ |x| seen.add?( yield( x ) ) }
  end
end

And we can use the following code:

@messages = Messages.all.uniq_by { |h| h.body }

I would like to know how and what happens when a method is called. Can anyone explain the internals of the code above? In the method, uniq_bywe did nothing to process the block argument. How is the passed argument handled by the method uniq_by?

+4
source share
4 answers

Ruby, yield (, #bar), #bar, #bar. yield , Proc, yield Proc .

:

def bar
   yield
end

p bar { "hello" } # "hello" 
p bar # bar': no block given (yield) (LocalJumpError)

uniq_by , . uniq_by?

, yield. , yield, , , . Messages.all.uniq_by { |h| h.body } { |h| h.body } uniq_by, Proc, yield Proc#call.

:

def bar
   p block_given? # true
   yield
end

bar { "hello" } # "hello"

:

class Array
  def uniq_by
    seen = Set.new
    select{ |x| seen.add?( yield( x ) ) }
  end
end

class Array
  def uniq_by
    seen = Set.new
    # Below you are telling uniq_by, you will be using a block with it
    # by using `yield`.
    select{ |x| var = yield(x); seen.add?(var) }
  end
end

yield

, ( ), . , yield . yield ; . yield - .

+1

:

seen = Set.new

select{ |x| seen.add?( yield( x ) ) }

Array#select , true.

seen.add?(yield(x)) true, , false, .

, yield(x) , uniq_by, x .

, { |h| h.body }, , seen.add?(x.body)

, add?, , false.

.body , , .

+3

uniq_by . , "".

yield body. , unique_by, , , body .

, : yield {|h| h.body} , h x , , x.body

+2

Array#select , , .

select Set#add?, , . add? nil, , .

( ) ( uniq_by) yield; yield - ({|h| h.body })

select .. :

select{ |x| seen.add?(x.body) }

, yield, .body .

+1

Source: https://habr.com/ru/post/1527676/


All Articles