Reputation: 1638
I have an array that looks like this:
strings= ['','','',' Some text', '', ' Some another text']
how can I map striped text only? right now I am doing this:
strings.select!{|string| !string.emtpy?}
strings.map!{|string| string.strip}
as you can see there are 2 loops. which I think is not efficient
Upvotes: 0
Views: 102
Reputation: 121
`strings.map {|string| string.strip if string.strip.size > 0}`.compact
> ["Some text", "Some another text"]
Explanation:
strings.map {|string| string.strip if string.strip.size > 0}
It will return:
> [nil, nil, nil, "Some text", nil, "Some another text"]
nil in case when string is empty. Else it will return stripped text.
.compact: Returns a copy of self with all nil elements removed.
So, [nil, nil, nil, "Some text", nil, "Some another text"].compact
will be:> ["Some text", "Some another text"]
Upvotes: 1
Reputation: 665
This is not most memory efficient (because you create another array) buy will do the job in one loop (There may be shorter ways to write this code. I am also using text!=''
instead emtpy?
because I do not use Rails
strings = ['','','',' Some text', '', ' Some another text']
stripped_strings = []
strings.each do |text|
if !(text=='')
stripped_strings << text.strip
end
puts stripped_strings
Output will be ['Some text','Some another text']
The next way works for me in Ruby 2.1.7 I am not sure it will work in other versions. And I think it is a little risky. But you will not need an extra Array
strings = ['','','',' Some text', '', ' Some another text']
strings.select! do |text|
text.strip!
text != ''
end
This works because that Ruby treats the String as an Object. Tell me comment If you want more explanation on this
A third option is also a little risky would be to delete the elements from the array while iterating on it. For this I am not using string.each
because removing items from array while running the each can be problematic also. Now I do not need to worry whether the each is cloning the the |text|
(then the strip! will not change the original array like in previous example)
strings = ['','','',' Some text', '', ' Some another text']
$i = strings.length - 1
while $i >= 0 do
if strings[$i] == ''
strings.delete_at($i)
else
strings[$i].strip!
end
$i -= 1
end
puts strings
Upvotes: 0
Reputation: 2747
You can also achieve that with #inject
(SO link, Ruby doc link) with one loop:
strings.inject([]) { |arr, val| val.present? ? arr.push(val.strip) : arr }
Upvotes: 0
Reputation: 9497
You can use grep
here:
strings.grep(/.+/, &:strip)
#=> ["Some text", "Some another text"]
Upvotes: 1
Reputation: 15045
You can just add lazy
not to create an intermediate array for every step.
It is still 2 iterations, but memory efficient, yet readable
strings.lazy.select {|string| !string.empty? }.map {|string| string.strip }.to_a
Upvotes: 1