grep-ing text in an array

A

aidy

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
 
K

Kenosis

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

Kenosis

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
}

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

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
 
R

Robert Klemme

aidy said:
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
 
A

aidy

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
 
R

Robert Klemme

aidy said:
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
 
A

aidy

Robert said:
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
 
R

Robert Klemme

aidy said:
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
 
R

Robert Klemme

Robert said:
aidy said:
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

Slight improvement so you get the position:

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

This can still be used in a boolean context.

Kind regards

robert
 
A

aidy

Robert said:
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,

I see what you are doing and it is a very 'neat' solution, but why the
for upper limit 'tab.size - ret.size'?

cheers

aidy
 
R

Robert Klemme

aidy said:
Robert said:
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,

I see what you are doing and it is a very 'neat' solution, but why the
for upper limit 'tab.size - ret.size'?

Um, didn't think that would be hard to determine. The code compares a
sliding window on the tab array with the ret array. It doesn't make
sense to use a starting index which would lead to a window which extends
past the end of tab. That's why.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top