0

I have an array of paragraphs and an array of keywords. I want to iterate over the paragraphs array and return true for elements that include all of my keywords. The keywords can be in any order, but all of them must be found in the same paragraph in order for it to be true, not just some of them.

Is there a way I can do this using one Regexp.union or one regex, without =~ regex1 && =~ regex2 && =~ regex3 && =~ regex4 etc?

sawa
  • 165,429
  • 45
  • 277
  • 381
GreenTriangle
  • 2,382
  • 2
  • 21
  • 35

3 Answers3

0

If the pattern array contains only keywords and no patters:

str = "foo went to bar with abc and xyz"

pats = ["abc","xyz","foo","bar"]
pats.all? { |e| str.include?(e) }
# => true

pats = ["abc","xyz","foo","bar", "no"]
pats.all? { |e| str.include?(e) }
# => false

If the pattern array contain patterns:

pats = [/abc/, /xyz$/, /^foo/, /bar/]
pats.all? { |e| str =~ e }
# => true

pats = [/abc/, /xyz$/, /^foo/, /bar/, /no/]
pats.all? { |e| str =~ e }
# => false
shivam
  • 16,048
  • 3
  • 56
  • 71
0

I suggest the following:

str = "I have an array of paragraphs and an array of keywords. I want to iterate over the paragraphs array and return true for elements that include all of my keywords. The keywords can be in any order, but all of them must be found in the same paragraph in order for it to be true, not just some of them."

Edit: I initially misunderstood the question. You can just do the following for each paragraph:

words = %w(have iterate true) 
(words - str.scan(/\w+/)).empty?
  #=> true

words = %w(have iterate cat)
(words - str.scan(/\w+/)).empty?
  #=> false

When I initially read the question I thought the words in the array must appear in each paragraph in the same order. For the record, my solution with that additional requirement follows.

words = %w(have iterate true)   
r = /\b#{words.join('\b.*?\b')}\b/
   #=> /\bhave\b.*?\biterate\b.*?\btrue\b/
str =~ r #=> 2 (a match)

words = %w(true have iterate)
r = /\b#{words.join('\b.*?\b')}\b/
str =~ r #=> nil

words = %w(have iterate true false)   
r = /\b#{words.join('\b.*?\b')}\b/
str =~ r #=> nil
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
-1

I have never used Ruby but I can give you the logic to use here. Hope it helps

array_words
array_paragraphs
number_words = array_words
count =0

foreach para (array_paragraph)
{
    foreach word (array_word)
    {
        if (para =~ m/word/gi)
        {
            count++
        }
    }
    if (count == number_words)
    {
        print all words present in the paragraph
    }
    count = 0
}
Rajinder
  • 41
  • 1
  • 9