"num in " in a cool way?

Hi, AFAIK in Ruby the only (or the “coolest”) way to do something as:

if num in [1,2,3,4]

is by doing:

if [1,2,3,4].index(num)

Is it? any other “cooler” way? Thanks.

On Aug 20, 2008, at 5:32 PM, Iñaki Baz C. wrote:


Iñaki Baz C.

if [1,2,3,4].include?(num)

if (1…4) === num

Robert might chime in with an inject version, so I won’t do one of
those.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On Wednesday 20 August 2008, Iñaki Baz C. wrote:

Hi, AFAIK in Ruby the only (or the “coolest”) way to do something as:

if num in [1,2,3,4]

is by doing:

if [1,2,3,4].index(num)

Is it? any other “cooler” way? Thanks.

if [1,2,3,4].include? num

It’s not that different, but it looks more like English.

Stefano

El Miércoles, 20 de Agosto de 2008, Rob B.
escribió:> if [1,2,3,4].include?(num)

if (1…4) === num

Thanks.

On Wed, Aug 20, 2008 at 2:32 PM, Iñaki Baz C. [email protected] wrote:

Hi, AFAIK in Ruby the only (or the “coolest”) way to do something as:

if num in [1,2,3,4]

is by doing:

if [1,2,3,4].index(num)

Is it? any other “cooler” way? Thanks.

class Object
def in? (other)
other.respond_to?(“include?”) && other.include?(self)
end
end

num.in? [1,2,3,4]

martin

On 20 Aug 2008, at 22:32, Iñaki Baz C. wrote:

Hi, AFAIK in Ruby the only (or the “coolest”) way to do something as:

if num in [1,2,3,4]

is by doing:

if [1,2,3,4].index(num)

Is it? any other “cooler” way? Thanks.

Well not saying this is actually a good idea, but…
class Object
def in(collection)
collection.include? self
end
end

if num.in [1,2,3,4]

end

On Wed, Aug 20, 2008 at 7:05 PM, Michael F.
[email protected] wrote:

num = 5
[*1…4].inject(num){|m,v| m == true ? m : (m == v || m) } == true

ary.inject([num, false]) {|(n,a), i| [n, a | (n == i)]}.last

martin

On Thu, Aug 21, 2008 at 6:41 AM, Rob B.
[email protected] wrote:

Is it? any other “cooler” way? Thanks.

РI̱aki Baz C.

if [1,2,3,4].include?(num)

if (1…4) === num

Robert might chime in with an inject version, so I won’t do one of those.

num = 5
[*1…4].inject(num){|m,v| m == true ? m : (m == v || m) } == true

But it’s far from cool, and my name isn’t Robert, but i hope it wakes
up the competitive spirit of all injectionalisits.

^ manveru

On Wed, Aug 20, 2008 at 8:03 PM, Mikael Høilund [email protected] wrote:

num = 5
ary.inject(false) { |m, v| true if m or v == num }

or even

ary.inject(false) { |m, v| m or v == num }

On Aug 21, 2008, at 4:58, Martin DeMello wrote:

On Wed, Aug 20, 2008 at 7:05 PM, Michael F.
[email protected] wrote:

num = 5
[*1…4].inject(num){|m,v| m == true ? m : (m == v || m) } == true

ary.inject([num, false]) {|(n,a), i| [n, a | (n == i)]}.last

num = 5
ary.inject(false) { |m, v| true if m or v == num }

2008/8/21 Martin DeMello [email protected]:

On Wed, Aug 20, 2008 at 8:03 PM, Mikael Høilund [email protected] wrote:

num = 5
ary.inject(false) { |m, v| true if m or v == num }

or even

ary.inject(false) { |m, v| m or v == num }

Disclaimer: I would not use #inject in this case.

But since you asked…

We can even short circuit with #inject:

irb(main):003:0> i = 3
=> 3
irb(main):004:0> (1…4).inject(nil) {|b,a| break a if i == a}
=> 3
irb(main):005:0> i = 10
=> 10
irb(main):006:0> (1…4).inject(nil) {|b,a| break a if i == a}
=> nil

But then again, you could directly use #find or even better #include?.

If it’s for integers I’d probably just do

irb(main):010:0> i = 3
=> 3
irb(main):011:0> i >= 1 && i <= 4
=> true
irb(main):012:0> (1…4) === i
=> true

Here’s a different approach:

irb(main):013:0> pat = (1…4).inject(0) {|x,a| x | 1 << a}
=> 30
irb(main):014:0> pat.to_s 2
=> “11110”
irb(main):015:0> pat[i] == 1
=> true

:slight_smile:

Kind regards

robert

On Wed, Aug 20, 2008 at 5:32 PM, Iñaki Baz C. [email protected] wrote:

Hi, AFAIK in Ruby the only (or the “coolest”) way to do something as:

if num in [1,2,3,4]

is by doing:

if [1,2,3,4].index(num)

Is it? any other “cooler” way? Thanks.

num.between?(1,4)

El Jueves, 21 de Agosto de 2008, Gregory B.
escribió:>

num.between?(1,4)

Great, I didn’t know! :slight_smile:

But in my case I’m using custom objects instead of Fixnum or String.

Thanks a lot.

On Thu, Aug 21, 2008 at 1:51 PM, Iñaki Baz C. [email protected] wrote:

num.between?(1,4)

Great, I didn’t know! :slight_smile:

But in my case I’m using custom objects instead of Fixnum or String.

Sure, this is implemented by Comparable, so you just need to include
that module and implement <=>

On Thu, Aug 21, 2008 at 1:38 PM, Robert K.
[email protected] wrote:

But then again, you could directly use #find or even better #include?.

In case of ranges #include? really should be your choice, it seems to
be optimized as one
might have expected…

511/12 > cat find-include.rb && ruby find-include.rb

vim: sw=2 ts=2 ft=ruby expandtab tw=0 nu:

require ‘benchmark’

R = (1…1_000)
N = 5
Benchmark::bmbm do |bm|
bm.report(“find”) do
N.times do
R.each do |ele|
R.find{ |e| e == ele}
R.find{ |e| e.zero? }
end
end
end
bm.report(“include?”) do
N.times do
R.each do |ele|
R.include? ele
R.include? 0
end
end
end
end
Rehearsal --------------------------------------------
find 6.797000 0.000000 6.797000 ( 6.828000)
include? 0.000000 0.000000 0.000000 ( 0.016000)
----------------------------------- total: 6.797000sec

           user     system      total        real

find 6.438000 0.000000 6.438000 ( 6.828000)
include? 0.016000 0.000000 0.016000 ( 0.016000)
HTH
Robert


use.inject do |as, often| as.you_can - without end
endless loops might run for quite some time though :wink:


http://ruby-smalltalk.blogspot.com/

There’s no one thing that’s true. It’s all true.

From: Iñaki Baz C. [mailto:[email protected]]

> num.between?(1,4)

Great, I didn’t know! :slight_smile:

careful. it just test the boundaries.

2.5.between?(1,4)
=> true

[1,2,3,4].include? 2.5
=> false

system “qri between”
---------------------------------------------------- Comparable#between?
obj.between?(min, max) => true or false


 Returns false if obj <=> min is less than zero or if anObject <=>
 max is greater than zero, true otherwise.

    3.between?(1, 5)               #=> true
    6.between?(1, 5)               #=> false
    'cat'.between?('ant', 'dog')   #=> true
    'gnu'.between?('ant', 'dog')   #=> false

kind regards -botp

On Fri, Aug 22, 2008 at 4:51 AM, Peña, Botp [email protected] wrote:

From: Iñaki Baz C. [mailto:[email protected]]

> num.between?(1,4)

Great, I didn’t know! :slight_smile:

careful. it just test the boundaries.
The same warning holds for Range#include? of course

2.5.between?(1,4)
=> true
(1…4).include? 2.5
=> true
R.

http://ruby-smalltalk.blogspot.com/

There’s no one thing that’s true. It’s all true.