[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

grep-ing text in an array

aidy

6/28/2006 5:46:00 PM

Hi,

I trying to find whether specific strings are contained within a array

table_array contains these elements [["", "95424", "Joe Stalin", "Field
Sales", "80%", "27/06/06", "", "Amend"]]

I am grep-ing whether the text I am looking for is in. So I have got an
array of regex

reg_text = /Stalin/, /Field Sales/, /80%/

Now, if the grep finds the string pattern a full string will be
returned
if x.grep(y) == /Stalin/
=> ["Joe Stalin"]

so, I have got another array

real_text = ["Joe Stalin"], ["Field Sales"], ["80%"]

this is the code

$table_array.each{|x|
reg_text.each{|y|
real_text.each{|z|
if x.grep(y) == z then p "#{z} is in table" end
}
}
}

But I think it is messy, and I wonder if there was a better way?

Cheers

aidy

14 Answers

Kenosis

6/28/2006 6:08:00 PM

0

Well, you could get rid of one level of iteration but using alternation
in your regex, e.g.,
/(Stalin|Sales|80)/


aidy wrote:
> Hi,
>
> I trying to find whether specific strings are contained within a array
>
> table_array contains these elements [["", "95424", "Joe Stalin", "Field
> Sales", "80%", "27/06/06", "", "Amend"]]
>
> I am grep-ing whether the text I am looking for is in. So I have got an
> array of regex
>
> reg_text = /Stalin/, /Field Sales/, /80%/
>
> Now, if the grep finds the string pattern a full string will be
> returned
> if x.grep(y) == /Stalin/
> => ["Joe Stalin"]
>
> so, I have got another array
>
> real_text = ["Joe Stalin"], ["Field Sales"], ["80%"]
>
> this is the code
>
> $table_array.each{|x|
> reg_text.each{|y|
> real_text.each{|z|
> if x.grep(y) == z then p "#{z} is in table" end
> }
> }
> }
>
> But I think it is messy, and I wonder if there was a better way?
>
> Cheers
>
> aidy

Jeff Schwab

6/28/2006 6:12:00 PM

0

aidy wrote:
> Hi,
>
> I trying to find whether specific strings are contained within a array
>
> table_array contains these elements [["", "95424", "Joe Stalin", "Field
> Sales", "80%", "27/06/06", "", "Amend"]]
>
> I am grep-ing whether the text I am looking for is in. So I have got an
> array of regex
>
> reg_text = /Stalin/, /Field Sales/, /80%/
>
> Now, if the grep finds the string pattern a full string will be
> returned
> if x.grep(y) == /Stalin/
> => ["Joe Stalin"]
>
> so, I have got another array
>
> real_text = ["Joe Stalin"], ["Field Sales"], ["80%"]
>
> this is the code
>
> $table_array.each{|x|
> reg_text.each{|y|
> real_text.each{|z|
> if x.grep(y) == z then p "#{z} is in table" end
> }
> }
> }
>
> But I think it is messy, and I wonder if there was a better way?

You can give grep a block directly:

a = [ "", "95424", "Joe Stalin", "Field Sales",
"80%", "27/06/06", "", "Amend" ]

re = /Stalin/, /Field Sales/, /80%/

re.each do |r|
a.grep(r) do |m|
puts m
end
end

# Output:
# Joe Stalin
# Field Sales
# 80%

Jeff Schwab

6/28/2006 6:14:00 PM

0

Jeffrey Schwab wrote:
> aidy wrote:
>> Hi,
>>
>> I trying to find whether specific strings are contained within a array
>>
>> table_array contains these elements [["", "95424", "Joe Stalin", "Field
>> Sales", "80%", "27/06/06", "", "Amend"]]
>>
>> I am grep-ing whether the text I am looking for is in. So I have got an
>> array of regex
>>
>> reg_text = /Stalin/, /Field Sales/, /80%/
>>
>> Now, if the grep finds the string pattern a full string will be
>> returned
>> if x.grep(y) == /Stalin/
>> => ["Joe Stalin"]
>>
>> so, I have got another array
>>
>> real_text = ["Joe Stalin"], ["Field Sales"], ["80%"]
>>
>> this is the code
>>
>> $table_array.each{|x|
>> reg_text.each{|y|
>> real_text.each{|z|
>> if x.grep(y) == z then p "#{z} is in table" end
>> }
>> }
>> }
>>
>> But I think it is messy, and I wonder if there was a better way?
>
> You can give grep a block directly:
>
> a = [ "", "95424", "Joe Stalin", "Field Sales",
> "80%", "27/06/06", "", "Amend" ]
>
> re = /Stalin/, /Field Sales/, /80%/
>
> re.each do |r|
> a.grep(r) do |m|
> puts m
> end
> end

Or, using Kenosis' idea:

a = [ "", "95424", "Joe Stalin", "Field Sales",
"80%", "27/06/06", "", "Amend" ]

re = /Stalin|Field Sales|80%/

a.grep(re) do |m|
puts m
end

Kenosis

6/28/2006 6:26:00 PM

0

Oops. Nix the parenthesis <blush> Can someone improve upon this -
hope so :)

ary = ["Stalin", "Field Sales", "80%", "FooBar"]
matches = ["Stalin", "Sales", "0%"]

pat = /#{matches.join('|')}/

ary.each { |s|
puts "match: #{$&}" if s =~ pat
}


Kenosis wrote:
> Well, you could get rid of one level of iteration but using alternation
> in your regex, e.g.,
> /(Stalin|Sales|80)/
>
>
> aidy wrote:
> > Hi,
> >
> > I trying to find whether specific strings are contained within a array
> >
> > table_array contains these elements [["", "95424", "Joe Stalin", "Field
> > Sales", "80%", "27/06/06", "", "Amend"]]
> >
> > I am grep-ing whether the text I am looking for is in. So I have got an
> > array of regex
> >
> > reg_text = /Stalin/, /Field Sales/, /80%/
> >
> > Now, if the grep finds the string pattern a full string will be
> > returned
> > if x.grep(y) == /Stalin/
> > => ["Joe Stalin"]
> >
> > so, I have got another array
> >
> > real_text = ["Joe Stalin"], ["Field Sales"], ["80%"]
> >
> > this is the code
> >
> > $table_array.each{|x|
> > reg_text.each{|y|
> > real_text.each{|z|
> > if x.grep(y) == z then p "#{z} is in table" end
> > }
> > }
> > }
> >
> > But I think it is messy, and I wonder if there was a better way?
> >
> > Cheers
> >
> > aidy

Robert Klemme

6/28/2006 9:00:00 PM

0

aidy wrote:
> Hi,
>
> I trying to find whether specific strings are contained within a array

Do you actually want this boolean information or do you want matching
strings returned?

# bool
texts.any? {|t| rxs.any? {|rx| rx =~ t}}

# texts
texts.select {|t| rxs.any? {|rx| rx =~ t}}

Alternatively join the RX's into one with alternation as suggested already.

Kind regards

robert

aidy

6/29/2006 1:36:00 PM

0

Hi,

Thank you all for the suggestions. But I think I may have gotten myself
into a hole

To just re-cap I need to log whether this array of strings

["Joe Stalin", "Field Sales", "80%"]

is contained within this

[ "", "95424", "Joe Stalin", "Field Sales", "80%", "27/06/06", "",
"Amend" ]

this is what I have done,

reg = /Stalin/, /Field Sales/, /80%/
ret = ["Joe Stalin", "Field Sales", "80%"]
tab = [ "", "95424", "Joe Stalin", "Field Sales", "80%", "27/06/06",
"", "Amend" ]

if tab.grep(/(Stalin|Sales|80)/) <=> ret then
puts 'pass' else puts "#{ret} not contained in table" end

But I am frustrated in that I am using similar arrays.

I think it is difficult if I do something like this to log when a
string is not found.

re.each do |r|
a.grep(r) do |m|
puts m
end
end

Thanks for the advice

aidy

Robert Klemme

6/29/2006 2:12:00 PM

0

aidy wrote:
> Hi,
>
> Thank you all for the suggestions. But I think I may have gotten myself
> into a hole
>
> To just re-cap I need to log whether this array of strings
>
> ["Joe Stalin", "Field Sales", "80%"]
>
> is contained within this
>
> [ "", "95424", "Joe Stalin", "Field Sales", "80%", "27/06/06", "",
> "Amend" ]
>
> this is what I have done,
>
> reg = /Stalin/, /Field Sales/, /80%/
> ret = ["Joe Stalin", "Field Sales", "80%"]
> tab = [ "", "95424", "Joe Stalin", "Field Sales", "80%", "27/06/06",
> "", "Amend" ]
>
> if tab.grep(/(Stalin|Sales|80)/) <=> ret then
> puts 'pass' else puts "#{ret} not contained in table" end
>
> But I am frustrated in that I am using similar arrays.
>
> I think it is difficult if I do something like this to log when a
> string is not found.
>
> re.each do |r|
> a.grep(r) do |m|
> puts m
> end
> end
>
> Thanks for the advice

Let's step back for the moment and recap your requirements. It seems to
me that they are not fully clear (at least not to me). From what I read
so far it seems you have this

Input: an arbitrary array, an array of strings

Output: true if the arbitrary array contains *all* of the strings in the
second array

The point where I'm not sure is whether you require the strings from the
second array to be
a) in arbitrary order
b) in sequence
c) in sequence possibly with other strings in between

This isn't clear to me from your description and example. And of course
this has dramatic effects on the algorithm chosen.

Kind regards

robert

aidy

6/29/2006 2:28:00 PM

0


Robert Klemme wrote:
> The point where I'm not sure is whether you require the strings from the
> second array to be
> a) in arbitrary order
> b) in sequence
> c) in sequence possibly with other strings in between

The second array will be a sequential sub-set of the first.

If the subset is not there I need to log a fail else a pass.

Cheers

aidy

Robert Klemme

6/29/2006 3:24:00 PM

0

aidy wrote:
> Robert Klemme wrote:
>> The point where I'm not sure is whether you require the strings from the
>> second array to be
>> a) in arbitrary order
>> b) in sequence
>> c) in sequence possibly with other strings in between
>
> The second array will be a sequential sub-set of the first.
>
> If the subset is not there I need to log a fail else a pass.

Ah, now we're cooking.

ret = ["Joe Stalin", "Field Sales", "80%"]
tab = [ "", "95424", "Joe Stalin", "Field Sales", "80%", "27/06/06", "",
"Amend" ]

def test(ret, tab)
for i in 0 .. tab.size - ret.size do
return true if ret == tab[i, ret.size]
end
false
end

test ret, tab

robert

Tim Hoolihan

6/29/2006 3:26:00 PM

0

Maybe I'm misunderstanding, but won't this do it:

class Array
def contains_set?(subset)
subset.each do |sub|
rval=false
self.each do |element|
rval=true if element.include?(sub)
end
return false if !rval
end
return true
end
end

data_set=["George","Bill","Tom","Joe"]
test_set1=["George","Tom"]
test_set2=["George","Mary"]

puts data_set.contains_set?(test_set1)
puts data_set.contains_set?(test_set2)


aidy wrote:
> Robert Klemme wrote:
>> The point where I'm not sure is whether you require the strings from the
>> second array to be
>> a) in arbitrary order
>> b) in sequence
>> c) in sequence possibly with other strings in between
>
> The second array will be a sequential sub-set of the first.
>
> If the subset is not there I need to log a fail else a pass.
>
> Cheers
>
> aidy
>