Finding if an array contains a data type

Say I wanted to see if an array contained a number or not. Would I use
the match method?

E.g.

x=["a","b",2, "c"]

puts("This array contains numbers") if x.match(/\d/)

I'm a real beginner at ruby, so simple explanations for simple folk
please. I appreciate your help.

···

--
Posted via http://www.ruby-forum.com/.

Not sure if this is the simplest way, but if you're looking for actual
numbers (not strings that look like numbers) you could do this:

puts("This array contains numbers") if x.find {|n| Numeric === n}

Cheers,
David

···

On Jan 3, 2008 6:27 PM, Sam Phoneix <dominicjefferies@yahoo.co.uk> wrote:

Say I wanted to see if an array contained a number or not. Would I use
the match method?

E.g.

x=["a","b",2, "c"]

puts("This array contains numbers") if x.match(/\d/)

Sam Phoneix wrote:

Say I wanted to see if an array contained a number or not. Would I use
the match method?

E.g.

x=["a","b",2, "c"]

puts("This array contains numbers") if x.match(/\d/)

I'm a real beginner at ruby, so simple explanations for simple folk
please. I appreciate your help.

Nice try, but match matches strings and you're wanting numbers.

Note that the Array class includes the Enumerable module, so all methods in Enumerable are available in Array. Enumerable has a method called "any?" that we can use. Here's what ri says about Enumerable#any?

$ ri Enumerable#any?
-------------------------------------------------------- Enumerable#any?
      enum.any? [{|obj| block } ] => true or false

···

------------------------------------------------------------------------
      Passes each element of the collection to the given block. The
      method returns true if the block ever returns a value other than
      false or nil. If the block is not given, Ruby adds an implicit
      block of {|obj| obj} (that is any? will return true if at least
      one of the collection members is not false or nil.

         %w{ ant bear cat}.any? {|word| word.length >= 3} #=> true
         %w{ ant bear cat}.any? {|word| word.length >= 4} #=> true
         [ nil, true, 99 ].any? #=> true

So, here's how to use it:

irb(main):001:0> x=["a","b",2, "c"]
=> ["a", "b", 2, "c"]
irb(main):002:0> x.any? {|p| p.is_a? Numeric}
=> true

--
RMagick: http://rmagick.rubyforge.org/
RMagick 2: http://rmagick.rubyforge.org/rmagick2.html

Several ways to test, but probably I'd like best

x=["a","b",2, "c"]
puts "This array contains numbers" if x.find{|t| t.kind_of?(Numeric)}

The method find is given to class Array by Enumerable, not so obvious.
Not knowing find nor kind_of?, I'd probably do

x=["a","b",2, "c"]
x.each { |t|
  if t.to_s =~ /^\d+(\.\d+)?$/ then
    puts "This array contains numbers"
    break
  end
}

But that's just ugly.

···

On Fri, 4 Jan 2008 09:27:05 +0900, "Sam Phoneix" <dominicjefferies@yahoo.co.uk> said:

Say I wanted to see if an array contained a number or not. Would I use
the match method?

E.g.

x=["a","b",2, "c"]

puts("This array contains numbers") if x.match(/\d/)

I'm a real beginner at ruby, so simple explanations for simple folk
please. I appreciate your help.
--
Posted via http://www.ruby-forum.com/\.

Sam Phoneix wrote:

Say I wanted to see if an array contained a number or not. Would I use
the match method?

E.g.

x=["a","b",2, "c"]

puts("This array contains numbers") if x.match(/\d/)

Another way, just for fun:

x=["a","b",2, "c"]
puts("This array contains numbers") unless x.grep(Numeric).empty?

Let's take apart what that means:

1. The Enumerable#grep method uses the "matching" operator === to search for all matches to the argument, which are collected into a new array.

2. In this case, grep's argument is a class, so each element of x is matched using the following condition: Numeric === the_element.

3. When called on classes, === checks if the given object is a member of the class (or a descendent) or not.

But this is not the most efficient solution since it has to pass over the entire collection (instead of stopping on the first match), and it makes a new array with the results. It's really only useful when you need all matches, for some reason. Otherwise, follow the suggestion to use #any? and #is_a? or #kind_of?.

References:

ri Module#===
ri Enumerable#grep

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

David Chelimsky wrote:

puts("This array contains numbers") if x.find {|n| Numeric === n}

Spot on, thanks.

···

--
Posted via http://www.ruby-forum.com/\.

Sam - I'd go with Tim's suggestion (.any?) rather than what I proposed (.find).

.find returns the first object in the Array, whereas .any? returns
boolean, which seems to be a better fit (semantically) for what you're
after.

Cheers,
David

···

On Jan 3, 2008 6:52 PM, Tim Hunter <TimHunter@nc.rr.com> wrote:

So, here's how to use it:

irb(main):001:0> x=["a","b",2, "c"]
=> ["a", "b", 2, "c"]
irb(main):002:0> x.any? {|p| p.is_a? Numeric}
=> true

> So, here's how to use it:
>
> irb(main):001:0> x=["a","b",2, "c"]
> => ["a", "b", 2, "c"]
> irb(main):002:0> x.any? {|p| p.is_a? Numeric}
> => true

Sam - I'd go with Tim's suggestion (.any?) rather than what I proposed (.find).

.find returns the first object in the Array, whereas .any? returns
boolean, which seems to be a better fit (semantically) for what you're
after.

Although I wonder what your opinion (Tim) is on is_a? vs ===.

···

On Jan 3, 2008 6:58 PM, David Chelimsky <dchelimsky@gmail.com> wrote:

On Jan 3, 2008 6:52 PM, Tim Hunter <TimHunter@nc.rr.com> wrote:

Cheers,
David

David Chelimsky wrote:

Although I wonder what your opinion (Tim) is on is_a? vs ===.

My opinion carries no weight whatsoever, but fwiw, I always use is_a? or kind_of? because it's not obvious what === does. Also I can't ever remember which order the arguments go :slight_smile:

···

--
RMagick: http://rmagick.rubyforge.org/
RMagick 2: http://rmagick.rubyforge.org/rmagick2.html

Tim Hunter wrote:

Also I can't ever
remember which order the arguments [of ===] go :slight_smile:

Try to remember it like this: The one that defines the behaviour of === (i.e.
the class, range or regexp) goes first.
But yeah, I don't usually explicitly use === either.

HTH,
Sebastian

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

I would say that === is more appropriate in the case where you are
generalizing and the thing you might match against will vary. This is
in fact what grep does - it will work on anything that responds to
===.

For example, it would be useful in the case of a find version of grep
(to solve the above problem with grep iterating over the whole array).
Let's call it grep_first:

class Array ; def grep_first pat ; find { | el | pat === el } ; end ;
end
array = ['foo','bar',2,'7','hi' ]
array.grep_first Numeric # => 2
array.grep_first /\d/ # => '7'
array.grep_first 'bar' # => 'bar'
array.grep_first 'foobar' # => nil

But if you specifically _know_ you are matching a type then I think
is_a or kind_of is probably better. Interested in others' take on
this.

Regards,
Dan

···

On Jan 3, 11:58 pm, Sebastian Hungerecker <sep...@googlemail.com> wrote:

But yeah, I don't usually explicitly use === either.

---
Dan Yoder
dev.zeraweb.com