[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Advanced conditionals

Alain m. Lafon

9/11/2008 9:44:00 AM

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
--
Posted via http://www.ruby-....

10 Answers

Alain m. Lafon

9/11/2008 10:03:00 AM

0

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).
--
Posted via http://www.ruby-....

Peña, Botp

9/11/2008 10:04:00 AM

0

RnJvbTogQWxhaW4gbS4gTGFmb24gW21haWx0bzpwcmVlay5hbWxAZ21haWwuY29tXSANCiMgaXMg
dGhlcmUgYSB3YXkgdG8gaW5jbHVkZSBjb25kaXRpb25hbHMgaW4gc29tZXRoaW5nIGxpa2U6DQoj
ICAgIGcubGFiZWxzID0gSGFzaFsqaW52b2ljZS5jb2xsZWN0IHt8dnwgW3ZbIlNjYW5kYXRlIl0u
dG9fcywNCiMgIjEiXX0uZmxhdHRlbl0NCiMgSW4gdGhpcyBleGFtcGxlIEkgZG9uJ3Qgd2FudCB0
byBpbmNsdWRlIGVudHJpZXMgdG8gdGhlIGhhc2ggd2hlcmUNCiMgdlsiU2NhbmRhdGUiXSBpcyBh
biBlbXB0eSBzdHJpbmcuDQoNCnlvdSdsbCBoYXZlIHRvIG1ha2UgdHdvIHBhc3NlcyAod2lzaCB0
aGVyZSB3YXMgYSByZWplY3Qvc2VsZWN0K21hcCBjb21iaSkNCg0Kc2FtcGxlLCAobm90ZSB1bnRl
c3RlZCwgaSBqdXN0IHR5cGUgaXQgaW4gdGhpcyBlbWFpbCA6KQ0KDQogIGcubGFiZWxzID0gSGFz
aFsqaW52b2ljZS5yZWplY3R7fHZ8IFt2WyJTY2FuZGF0ZSJdLiB0b19zLnN0cmlwLiBlbXB0eT99
LiBjb2xsZWN0e3x2fCBbdlsiU2NhbmRhdGUiXS50b19zLCAiMSJdfS5mbGF0dGVuXQ0KDQoNCg==

Pedro Silva

9/11/2008 10:08:00 AM

0

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 Silva.
--
Posted via http://www.ruby-....

Peña, Botp

9/11/2008 10:13:00 AM

0

IyBzYW1wbGUsIChub3RlIHVudGVzdGVkLCBpIGp1c3QgdHlwZSBpdCBpbiB0aGlzIGVtYWlsIDop
DQojIA0KIyAgIGcubGFiZWxzID0gSGFzaFsqaW52b2ljZS5yZWplY3R7fHZ8IFt2WyJTY2FuZGF0
ZSJdLiANCg0KICAgICAgICAgICAgLi4uLi4gaSB0aGluayAgdGhpcyBicmFja2V0IF4gc2hvdWxk
IGJlIHJlbW92ZWQsIHNvcnJ5DQoNCiMgdG9fcy5zdHJpcC4gZW1wdHk/fS4gY29sbGVjdHt8dnwg
W3ZbIlNjYW5kYXRlIl0udG9fcywgIjEiXX0uZmxhdHRlbl0NCiMgDQojIA0KIyANCg==

Robert Dober

9/11/2008 11:26:00 AM

0

On Thu, Sep 11, 2008 at 11:43 AM, Alain m. Lafon <preek.aml@gmail.com> wrot=
e:
> Hi there,
>
> is there a way to include conditionals in something like:
>
> g.labels =3D 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
> --
> Posted via http://www.ruby-....
>
>

I sometimes decide against the map.select (or better select.map )
chaining using compact

ary.map{ |x| c(x) && f(x) }.compact

HTH
Robert

--=20
C'est v=E9ritablement utile puisque c'est joli.

Antoine de Saint Exup=E9ry

Peña, Botp

9/12/2008 1:27:00 AM

0

From: David A. Black [mailto:dblack@rubypal.com]=20
.
#For a little while, 1.9 allowed you to do this:
#>> e =3D [1,2,3].enum_for(:map, &lambda {|x| x * 10 })
#=3D> #<Enumerable::Enumerator:0x39038c>
#>> e.select {|n| n > 10 }
#=3D> [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 =3D [1,2,3].select{|n| n>1}.map{|x| x*10}
=3D>[20,30]

i was actually dreaming of ruby supporting multiple blocks
so that you can do simply

> e =3D [1,2,3].select{|n| n>1},{|x| x*10}
=3D>[20,30]

meaning, do a (re)map if a second code block is passed

kind regards -botp


Bill Kelly

9/12/2008 11:35:00 PM

0


From: "David A. Black" <dblack@rubypal.com>
>
> [...] 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.

Maybe worth asking on ruby-core? Still 13 days till the
feature freeze...!



Regards,

Bill



David A. Black

9/12/2008 11:38:00 PM

0

Hi --

On Sat, 13 Sep 2008, Bill Kelly wrote:

>
> From: "David A. Black" <dblack@rubypal.com>
>>
>> [...] 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.
>
> 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

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.r... for details and updates!

Peña, Botp

9/13/2008 4:13:00 AM

0

From: David A. Black [mailto:dblack@rubypal.com]=20
...
>> e =3D [1,2,3].select{|n| n>1},{|x| x*10}
> =3D>[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



Peña, Botp

9/18/2008 1:17:00 AM

0

From: David A. Black [mailto:dblack@rubypal.com]=20
.
>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