Hi there,
is there a way to include conditionals in something like:
g.labels = Hash[*invoice.collect {|v| [v[“Scandate”].to_s,
“1”]}.flatten]
In this example I don’t want to include entries to the hash where
v[“Scandate”] is an empty string.
Help is as always very much appreciated - thanks in advance,
Alain M. Lafon
I forgot to mention that I do realize that there is an delete_if option
for Hashes. Probably I should have searched for a better example, but
what I want to know is wheter I can implement small functions in any
statement(like lambdas in Lisp).
H,
g.labels = Hash[*invoice.collect {|v| [v[“Scandate”].to_s,
“1”]}.flatten]
In this example I don’t want to include entries to the hash where
v[“Scandate”] is an empty string.
The method collect/map has “friends”. What you’re looking for is select
or reject. Select returns the elements from the container where the
condition specified in the block evaluates to true, reject does the
opposite - returns the elements that evaluate to false.
Consider the following example:
invoice = {:a => “a”, :b => “b”, :c => “”, :d => “c”, :e => “”}
invoice.select { |a, b| b != “” } # [[:a, “a”], [:b, “b”], [:d, “c”]]
Pedro S…
From: Alain m. Lafon [mailto:[email protected]]
is there a way to include conditionals in something like:
g.labels = Hash[*invoice.collect {|v| [v[“Scandate”].to_s,
“1”]}.flatten]
In this example I don’t want to include entries to the hash where
v[“Scandate”] is an empty string.
you’ll have to make two passes (wish there was a reject/select+map
combi)
sample, (note untested, i just type it in this email
g.labels = Hash[*invoice.reject{|v| [v[“Scandate”]. to_s.strip.
empty?}. collect{|v| [v[“Scandate”].to_s, “1”]}.flatten]
sample, (note untested, i just type it in this email
g.labels = Hash[*invoice.reject{|v| [v[“Scandate”].
..... i think this bracket ^ should be removed, sorry
to_s.strip. empty?}. collect{|v| [v[“Scandate”].to_s, “1”]}.flatten]
Hi –
On Thu, 11 Sep 2008, Peña, Botp wrote:
From: Alain m. Lafon [mailto:[email protected]]
is there a way to include conditionals in something like:
g.labels = Hash[*invoice.collect {|v| [v[“Scandate”].to_s,
“1”]}.flatten]
In this example I don’t want to include entries to the hash where
v[“Scandate”] is an empty string.
you’ll have to make two passes (wish there was a reject/select+map combi)
For a little while, 1.9 allowed you to do this:
e = [1,2,3].enum_for(:map, &lambda {|x| x * 10 })
=> #Enumerable::Enumerator:0x39038c
e.select {|n| n > 10 }
=> [20, 30]
But #enum_for no longer accepts a &block-style argument. The same code
in current 1.9 would give you [], because it would ignore the lambda
and just do a pass-through mapping.
I’m still unclear as to why this behavior was removed. It seems to me
that its removal reduces the usefulness of enumerators drastically.
David
On Thu, Sep 11, 2008 at 11:43 AM, Alain m. Lafon [email protected]
wrote:
Help is as always very much appreciated - thanks in advance,
Alain M. Lafon
Posted via http://www.ruby-forum.com/.
I sometimes decide against the map.select (or better select.map )
chaining using compact
ary.map{ |x| c(x) && f(x) }.compact
HTH
Robert
–
C’est véritablement utile puisque c’est joli.
Antoine de Saint Exupéry
From: David A. Black [mailto:[email protected]]
…
#For a little while, 1.9 allowed you to do this:
#>> e = [1,2,3].enum_for(:map, &lambda {|x| x * 10 })
#=> #Enumerable::Enumerator:0x39038c
#>> e.select {|n| n > 10 }
#=> [20, 30]
#But #enum_for no longer accepts a &block-style argument. The same code
#in current 1.9 would give you [], because it would ignore the lambda
#and just do a pass-through mapping.
#I’m still unclear as to why this behavior was removed. It seems to me
#that its removal reduces the usefulness of enumerators drastically.
maybe because it does not look any better than the simpler (but less
efficient)
e = [1,2,3].select{|n| n>1}.map{|x| x*10}
=>[20,30]
i was actually dreaming of ruby supporting multiple blocks
so that you can do simply
e = [1,2,3].select{|n| n>1},{|x| x*10}
=>[20,30]
meaning, do a (re)map if a second code block is passed
kind regards -botp
Hi –
On Fri, 12 Sep 2008, Peña, Botp wrote:
#I’m still unclear as to why this behavior was removed. It seems to me
#that its removal reduces the usefulness of enumerators drastically.
maybe because it does not look any better than the simpler (but less efficient)
e = [1,2,3].select{|n| n>1}.map{|x| x*10}
=>[20,30]
It’s not really about the visual appearance of this or that example,
though; it’s more about efficiency, since that’s supposed to be one of
the big advantages of enumerators. The other advantage is that you can
call next and rewind… but you cannot, any longer, do this:
irb(main):007:0> a = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):008:0> e = a.enum_for(:map, &lambda {|x| x * 10 })
=> #Enumerable::Enumerator:0x3d7444
irb(main):009:0> e.next
=> 10
You’ll get 1 now, rather than 10. I’m still very puzzled by the
removal of this capability.
i was actually dreaming of ruby supporting multiple blocks
so that you can do simply
e = [1,2,3].select{|n| n>1},{|x| x*10}
=>[20,30]
meaning, do a (re)map if a second code block is passed
That comes up periodically… It never appealed to me; I guess I
think of it like a method having two argument lists. Besides, how
would you distinguish it from a hash literal?
David
Hi –
On Sat, 13 Sep 2008, Bill K. wrote:
=> 10
You’ll get 1 now, rather than 10. I’m still very puzzled by the
removal of this capability.
Maybe worth asking on ruby-core? Still 13 days till the
feature freeze…!
I did. Shugo did discuss it some, but I’m afraid I still didn’t
understand, or maybe I just wasn’t convinced. I think it probably
boils down to efficiency, though it seems to me to be an example of
something so powerful and potentially useful that efficiency wouldn’t
(up to a point) be a deal-breaker.
David
From: “David A. Black” [email protected]
You’ll get 1 now, rather than 10. I’m still very puzzled by the
removal of this capability.
Maybe worth asking on ruby-core? Still 13 days till the
feature freeze…!
Regards,
Bill
Hi –
On Sat, 13 Sep 2008, Peña, Botp wrote:
i prefer that code blocks be generics and be passed like normal
arguments. ergo, they will now be explicitly defined in def. less
invisible ink?
It’s not really an invisible ink thing – more about the semantics or
anatomy of a method call. The thing is, you can already pass procs as
normal arguments, so if you allow that to happen without specifying
that they are procs (i.e., {} instead of proc {}), the main effect is
that you lose the concept of the code block, and presumably you lose
yield.
So all you gain, really, is not having to write “proc”. I don’t think
it’s worth it; I like the whole block/yield/iterator thing too much.
would you distinguish it from a hash literal?
strengthen the parser. currently, since a code block come last, then
the rest should be code blocks, if any. also, if a token arg
sequence of “{|” is caught, then that should start a code block.
meaning {||} is always a code block.
That’s ugly, though – you’d end up with a lot of empty ||'s.
David
From: David A. Black [mailto:[email protected]]
…
So all you gain, really, is not having to write “proc”. I don’t think
it’s worth it; I like the whole block/yield/iterator thing too much.
i like yield, too. so much, that i want another yield.
how about yield_next to yield to the next block? we allow max of two
blocks only…
That’s ugly, though – you’d end up with a lot of empty ||'s.
it’s not too ugly if it’s not empty since we usually end up passing proc
args anyway. in 1.9 we have ->{}, and as compared to {||}, we get same
number of characters yet i still prefer the latter considering that i’m
used to it and it’s still is clearer/cleaner.
but anyway, this feature is no big deal to me. i’m even happy passing
array of procs or just looping w each instead of select+map. it’s just
that sometimes i wish there was some way i code just type in easily like
select+map combination in one simple streamlined fast code…
thank you for the discussion.
kind regards -botp
From: David A. Black [mailto:[email protected]]
…
e = [1,2,3].select{|n| n>1},{|x| x*10}
=>[20,30]
meaning, do a (re)map if a second code block is passed
That comes up periodically… It never appealed to me; I guess I
think of it like a method having two argument lists. Besides, how
indeed. and i think we agree to disagree there.
i prefer that code blocks be generics and be passed like normal
arguments. ergo, they will now be explicitly defined in def. less
invisible ink?
would you distinguish it from a hash literal?
strengthen the parser. currently, since a code block come last, then the
rest should be code blocks, if any. also, if a token arg sequence of
“{|” is caught, then that should start a code block. meaning {||} is
always a code block.
kind regards -botp