Reputation:
Using Ruby 2.4. I have an arry with a numbegr of string elements. I would like to strip off elemetns that are either nil or empty from teh end of the array so I have
row_data.pop until row_data.last || row_data.empty?
But this is only stripping the nil elements off the end of the array. How do I adjust the above so that it also includes thte empty elements?
Upvotes: 1
Views: 1159
Reputation: 110745
If the array contains only strings and nil
s, one could write:
row_data = ["cat", nil, '', nil]
row_data.tap { |rd| pop while rd.last.to_s.empty? }
#=> ["cat"]
Note nil.to_s #=> ''
.
If array
may contain other objects as well, one may write:
row_data = ['', 1, :cat, {}, [], nil]
row_data.tap { |rd| rd.pop while (rd.last.nil? ||
(row_data.last.respond_to?(:empty?) && row_data.last.empty?)) }
#=> ["", 1, :cat]
Upvotes: 1
Reputation: 802
row_data = [ "", "hi", "", nil ] # => ["", "hi", "", nil]
row_data.pop while !row_data.empty? && (!row_data.last || row_data.last.empty?) # => nil
row_data # => ["", "hi"]
Very similar to your solution but instead we flip from while to unless cause instead of looking for the PRESENCE of an object we are looking for nil
explicitly. Then we check if that string is empty. You could check if the last element has the method empty?
if you expect other object types to be present in your array. (But I assume you are parsing CSV so it's most likely a moot point)
If you have active_support or are inside of rails this gets easier.
# Ignore the require if in a rails project
require 'active_support/core_ext/object/blank' # => true
row_data = [ "", "hi", "", nil ] # => ["", "hi", "", nil]
row_data.pop while !row_data.empty? && row_data.last.blank? # => nil
row_data # => ["", "hi"]
Below would remove nil or empty string from ANY position of an array
row_data = [ "hi", "", nil ]
row_data.compact.reject(&:empty?) # => ["hi"]
Given an array of strings, and assuming no active_support
this will remove any nil value compact
and then reject any string that is empty reject(&:empty?)
This does create a new array, and does not make any changes in place. If you need to mutate the original object use the following code
row_data = [ "hi", "", nil ]
row_data.compact!.reject!(&:empty?) # => ["hi"]
row_data # => ["hi"]
If you have active support this could be reduced to
row_data = [ "hi", "", nil ]
row_data.reject(&:blank?) # => ["hi"]
Upvotes: 4