Thanks Joel,
Do you think this could/should be added to the standard library or to
the Facets library?
Eric.
Eric TORREBORRE
tel: +81 (0)90 5580 3280
e-mail: removed_ema[email protected] / [email protected]
blog: http://etorreborre.blogspot.com
----- Message d’origine ----
De : Joel VanderWerf [email protected]
À : ruby-talk ML [email protected]
Envoyé le : Vendredi, 1 Juin 2007, 2h21mn 21s
Objet : Re: Set intersection with a specific criteria: a better idiom?
Eric T. wrote:
end
end
n
endI have met this requirement quite some times while scripting and I may miss something here.
Do you know a more idiomatic, Ruby-way of doing that?
Hm, it’s like Schwartzian transform: intersect_by instead of sort_by.
Your implementation looks good, but might be more efficient with:
mapped = self.class.new(map{|e| property.call(e)})
which would make mapped a set, for faster lookups.
Also, using yield will probably be more efficient than instantiating a
proc and calling it:
def &(enum)
n = self.class.new
if block_given?
mapped = self.class.new(map{|e| yield e})
enum.each { |o| n.add(o) if mapped.include?(yield o) }
else
enum.each { |o| n.add(o) if include?(o) }
end
n
end
It would be more elegant to use select than to iterate through enum
using #each and #add to the set, but Set#select returns an Array. At the
cost of using two iterations instead of once, you could do this:
require ‘set’
class Set
def intersect_by(other)
props = self.class.new(other.map {|t| yield t})
self.class.new(select {|t| props.include? t.prop})
end
Actually the following is closer to the origial:
def intersect_by(other)
props = self.class.new(map {|t| yield t})
self.class.new(other.select {|t| props.include? t.prop})
end
alias old_intersect &
def &(other)
if block_given?
intersect_by(other) {|t| yield t}
else
old_intersect(other) {|t| yield t}
end
end
end
class Test
attr_accessor :prop
def initialize prop
@prop = prop
end
end
s1 = Set.new([
Test.new(1),
Test.new(2),
Test.new(3)
])
s2 = Set.new([
Test.new(2),
Test.new(3),
Test.new(4)
])
p(s1.intersect_by(s2) {|t| t.prop})
p(Set[1,2,3]&Set[2,3,4])
END
#<Set: {#<Test:0xb79f73e4 @prop=2>, #<Test:0xb79f73d0 @prop=3>}>
#<Set: {2, 3}>
–
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
Découvrez une nouvelle façon d’obtenir des réponses à toutes vos
questions !
Profitez des connaissances, des opinions et des expériences des
internautes sur Yahoo! Questions/Réponses