2

I want to search an array for a certain string and(!) its substrings. For example my array is:

array = ["hello", "hell", "goodbye", "he"]

So when I search for "hello" and its substrings (but only from the beginning: "he", "hell", "hello"), it should return

=> ["hello", "hell", "he"]

What I've tried so far: Using a regular expression with the #grep and/or the #include? method like this:

array.grep("hello"[/\w+/])

or

array.select {|i| i.include?("hello"[/\w+/])}

but in both cases it only returns

=> ["hello"] 

By the way, if I try array.select{|i| i.include?("he")} it works but like I said I want it the other way around: searching for "hello" and give me all results including the substrings from the beginning.

2
  • e is a substring of hello so goodbye should be in result. Or did you mean substrings only from beginning of the string? h,he,hel...hello? Commented Mar 10, 2015 at 16:17
  • yes, I mean only from the beginning of the string Commented Mar 10, 2015 at 16:18

7 Answers 7

3
require "abbrev"

arr = ["hello", "hell", "goodbye", "he"]
p arr & ["hello"].abbrev.keys # => ["hello", "hell", "he"]
Sign up to request clarification or add additional context in comments.

2 Comments

That's just... beautiful
That's very cool. I'd never heard of the module Abbrev, but considering it contains but a single method, I'm probably not alone. Those wanting more information (you can supply an optional pattern, for example) may wish to read this.
2
array = ["hello", "hell", "goodbye", "he", "he"]

# define search word:
search = "hello"

# find all substrings of this word:
substrings = (0..search.size - 1).each_with_object([]) { |i, subs| subs << search[0..i] }
#=> ["h", "he", "hel", "hell", "hello"]

# find intersection between array and substrings(will exclude duplicates):
p array & substrings
#=> ["hello", "hell", "he"]

# or select array elements that match any substring(will keep duplicates):
p array.select { |elem| substrings.include?(elem) }
#=> ["hello", "hell", "he", "he"]

Comments

2

I'd use String#[] :

array = ["hello", "hell", "goodbye", "he", "he"]
search = "hello"
array.select { |s| search[/\A#{s}/] }
# => ["hello", "hell", "he", "he"]

Comments

1

Turn all the characters other than h in hello to optional.

> array = ["hello", "hell", "goodbye", "he"]
> array.select{|i| i[/^he?l?l?o?/]}
=> ["hello", "hell", "he"]

2 Comments

Could my eyes be deceiving me? Is it possible that the regex-master got it wrong? ["hl"].select{|i| i[/^he?l?l?o?/]} #=> ["hl"].
Cary. Then he need to put hello,he'll,hel,he inside a non capturing group. Texting from my mobile so I can't able to add that.Regex master? no. I didn't get into that level.
1

You could still use a regular expression like this

#define Array
arr = ["hello", "hell", "goodbye", "he"]
#define search term as an Array of it's characters
search = "hello".split(//)
#=> ['h','e','l','l','o']
#deem the first as manditory search.shift
#the rest are optional ['e?','l?','l?','o?'].join
search = search.shift << search.map{|a| "#{a}?"}.join
#=> "he?l?l?o?"
#start at the beginning of the string \A
arr.grep(/\A#{search}/)
#=> ["hello", "hell", "he"]

Comments

1

Just as the question reads:

array.select { |w| "hello" =~ /^#{w}/ }
  #=> ["hello", "hell", "he"]

Comments

0

Use array#keep_if

array = ["hello", "hell", he"]
substrings = array.keep_if{|a| a.start_with?('h')}
=> ["hello", "hell", "he"]

3 Comments

thanks, but isn't it the same as array.select{ |a| a.include?("h")} (in my example).
Apparently it's not, because yours only returned "hello", mine returned what you were looking for. And also, include finds all elements that contain a string. start_with only finds strings that start with a string
If array = ['hat'], 'hat' is returned, but 'hat' is not a substring of 'hello'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.