user7055375
user7055375

Reputation:

How do I strip off nil or empty elements from the end of my array?

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

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110745

If the array contains only strings and nils, 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

rposborne
rposborne

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

Related Questions