How to make a method to split two strings in an array? - ruby

I'm trying to return two strings in an array into individual words:
list = ['hello my name is ryan', 'hole me llamo']
def splitter(inp)
inp.each.split(' ')
end
print splitter(list)
This returns:
ruby splitter.rb
splitter.rb:4:in `splitter': undefined method `strsplit' for # <Enumerator: ["hello my name is ryan", "hole me llamo"]:each> (NoMethodError)
from splitter.rb:7:in `<main>'
It works if I don't use .each and use inp(0) or inp(1) but only one string returns.
How can I get both strings to be returned?

Here is one you should do :
def splitter(inp)
inp.flat_map(&:split)
end
splitter list
# => ["hello", "my", "name", "is", "ryan", "hole", "me", "llamo"]
In your code inp.each was actually a method call like Array#each, which without a block gives an Enumerator. And String#spilt does exist, but there is not method like Enumerator#split, that's why NoMethod error blows up.
And if you want the array of words for each individual strings, then
def splitter(inp)
inp.map(&:split)
end
splitter list
# => [["hello", "my", "name", "is", "ryan"], ["hole", "me", "llamo"]]

If I understand the question correctly, it's just:
list = ['hello my name is ryan', 'hole me llamo']
list.join(' ').split
#=> ["hello", "my", "name", "is", "ryan", "hole", "me", "llamo"]

Related

How to get index of value in anonymous array inside of iteration

I would like to be able to take an anonymous array, iterate through it and inside of the iterator block find out what the index is of the current element.
For instance, I am trying to output only every third element.
["foo", "bar", "baz", "bang", "bamph", "foobar", "Hello, Sailor!"].each do |elem|
if index_of(elem) % 3 == 0 then
puts elem
end
end
(where index_of is a nonexistent method being used as a placeholder here to demonstrate what I'm trying to do)
In theory the output should be:
foo
bang
Hello, Sailor!
This is pretty straightforward when I'm naming the array. But when it is anonymous, I can't very well refer to the array by name. I've tried using self.find_index(elem) as well as self.index(elem) but both fail with the error: NoMethodError: undefined method '(find_)index' for main:Object
What is the proper way to do this?
Use each_with_index:
arr = ["foo", "bar", "baz", "bang", "bamph", "foobar", "Hello, Sailor!"]
arr.each_with_index do |elem, index|
puts elem if index % 3 == 0
end
Another way:
arr = ["foo", "bar", "baz", "bang", "bamph", "foobar", "Hello, Sailor!"]
arr.each_slice(3) { |a| puts a.first }
#=> foo
# bang
# Hello, Sailor!

What's the Ruby equivalent of map() for strings?

If you wanted to split a space-separated list of words, you would use
def words(text)
return text.split.map{|word| word.downcase}
end
similarly to Python's list comprehension:
words("get out of here")
which returns ["get", "out", "of", "here"]. How can I apply a block to every character in a string?
Use String#chars:
irb> "asdf".chars.map { |ch| ch.upcase }
=> ["A", "S", "D", "F"]
Are you looking for something like this?
class String
def map
size.times.with_object('') {|i,s| s << yield(self[i])}
end
end
"ABC".map {|c| c.downcase} #=> "abc"
"ABC".map(&:downcase) #=> "abc"
"abcdef".map {|c| (c.ord+1).chr} #=> "bcdefg"
"abcdef".map {|c| c*3} #=> "aaabbbcccdddeeefff"
I think the short answer to your question is "no, there's nothing like map for strings that operates a character at a time." Previous answerer had the cleanest solution in my book; simply create one by adding a function definition to the class.
BTW, there's also String#each_char which is an iterator across each character of a string. In this case String#chars gets you the same result because it returns an Array which also responds to each (or map), but I guess there may be cases where the distinction would be important.

How to collect only string instances from a collection?

I have an array, which is comprising of different kind of objects. But I would like to get only the string instances. What i wrote as below :
ary = ["11",1,2,"hi",[11]]
ary.select{|e| e.instance_of? String } # => ["11", "hi"]
I am looking for an elegant way of doing this, if any.
I would do as below using Enumerable#grep :
Returns an array of every element in enum for which Pattern === element. If the optional block is supplied, each matching element is passed to it, and the block’s result is stored in the output array.
ary = ["11",1,2,"hi",[11]]
ary.grep(String) # => ["11", "hi"]
You may want to try Object#is_a? method:
ary = ["11", 1, 2, "hi", [11]]
ary.select{|e| e.is_a? String }
# Output
=> ["11", "hi"]
Can't do better than grep, but here's another:
ary.group_by(&:class)[String] # => ["11", "hi"]

Strip in collect on splitted array in Ruby

The following code:
str = "1, hello,2"
puts str
arr = str.split(",")
puts arr.inspect
arr.collect { |x| x.strip! }
puts arr.inspect
produces the following result:
1, hello,2
["1", " hello", "2"]
["1", "hello", "2"]
This is as expected. The following code:
str = "1, hello,2"
puts str
arr = (str.split(",")).collect { |x| x.strip! }
puts arr.inspect
Does however produce the following output:
1, hello,2
[nil, "hello", nil]
Why do I get these "nil"? Why can't I do the .collect immediately on the splitted-array?
Thanks for the help!
The #collect method will return an array of the values returned by each block's call. In your first example, you're modifying the actual array contents with #strip! and use those, while you neglect the return value of #collect.
In the second case, you use the #collect result. Your problem is that #strip! will either return a string or nil, depending on its result – especially, it'll return nil if the string wasn't modified.
Therefore, use #strip (without the exclamation mark):
1.9.3-p194 :005 > (str.split(",")).collect { |x| x.strip }
=> ["1", "hello", "2"]
Because #strip! returns nil if the string was not altered.
In your early examples you were not using the result of #collect, just modifying the strings with #strip!. Using #each in that case would have made the non-functional imperative loop a bit more clear. One normally uses #map / #collect only when using the resulting new array.
You last approach looks good, you wrote a functional map but you left the #strip! in ... just take out the !.

Ruby Array changing substring

I would like to display the following:
anu1 cau1 doh1 bef1
To do that I need to complete the following Ruby code by adding only ONE statement.
a = ["ant", "cat", "dog", "bee"]
It sounds like you need to perform a succ function each of the words, which will give you the next value for each of them, then you would just need to append "1" to each.
Example: -Forgive my syntax, Haven't used Ruby in a while-
a.map {|word| word.succ << "1"}
should output:
["anu1", "cau1", "doh1", "bef1"]
a = ["ant", "cat", "dog", "bee"]
# => ["ant", "cat", "dog", "bee"]
a.map {|str| str.succ << "1" }
# => ["anu1", "cau1", "doh1", "bef1"]

Resources