13

I'm dealing with a bunch of arrays made of strings and many a times I've written .delete_if { |str| str.empty? }

Now, I know I can add this method to the array class myself but I'm hoping there's a built in way to do this without having non-standard methods added to base classes. As much fun as adding methods to base classes is, it's not something I wanna do for maintainability reasons.

Is there a built in method to handle this?

Drew
  • 15,158
  • 17
  • 68
  • 77
  • I have the same problem as you. Almost always, I want to do that right before `join`, so in my case, I made a method similar to `join` but removes blanks previously. – sawa Apr 25 '11 at 21:14
  • 1
    so what is the question? – fl00r Apr 25 '11 at 21:14
  • 1
    @fl00r Whether or not there is a built in way to do it. – sawa Apr 25 '11 at 21:15
  • @sawa, there is `compact` method that deletes all nil elements, but there is no standart method to delete all empty strings. – fl00r Apr 25 '11 at 21:17
  • @fl00r Right. That will be the short answer to the question. – sawa Apr 25 '11 at 21:19
  • `compact` doesn't delete elements, it returns a new array not containing the elements. Non-destructive methods are generally easier to use as they do not depend on side effects. – Rein Henrichs Apr 25 '11 at 21:19
  • 3
    @Rein Henrichs, okey there is `compact!` method :) – fl00r Apr 25 '11 at 21:20
  • 1
    What's wrong with just adding a new method to the Array class? –  Apr 25 '11 at 21:22
  • 1
    Nothing wrong if it is well documented before usage and if it is clear for all teamworkers :) – fl00r Apr 25 '11 at 21:23
  • Possible duplicate of [How do I remove blank elements from an array?](http://stackoverflow.com/questions/5878697/how-do-i-remove-blank-elements-from-an-array) – Felix Oct 01 '15 at 12:43
  • Some great work-arounds, but unfortunately the actual answer is **no.** – Drew Apr 26 '11 at 14:03

9 Answers9

40

There is a short form

array.delete_if(&:empty?)
SET001
  • 11,480
  • 6
  • 52
  • 76
fl00r
  • 82,987
  • 33
  • 217
  • 237
  • 2
    If you are using Rails, array.delete_if(&:blank?) is a better option to avoid a NoMethodError if one of the values is nil. – jesal Apr 21 '15 at 00:58
  • 2
    `array.compact.delete_if(&:empty?)` will handle the nil and the blank in pure Ruby. – scarver2 Jan 25 '16 at 18:08
8

You can use this method:

    1.9.3p194 :001 > ["", "A", "B", "C", ""].reject(&:empty?)
    => `["A", "B", "C"]`

Please note that you can use the compact method if you only got to clear an array from nils.

sidney
  • 2,704
  • 3
  • 28
  • 44
5

Well, there is Array.delete. It returns what's deleted (or nil if nothing is deleted) however, which feels clumsy. But it does deliver and does not fail on non-string elements:

ar = ['a', '', 2, 3, '']
p ar.delete('')  #=> ""
p ar             #=> ["a", 2, 3]
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • I like this one. Some weeks ago on SO was discussion about method that deletes an element and returns itself. like `array.delete(element); array` – fl00r Apr 26 '11 at 08:09
1

You can do this

ar = ['a', '', 2, 3, '']
ar = ar.select{|a| a != ""}

I hope this will work for you

Asnad Atta
  • 3,855
  • 1
  • 32
  • 49
0

You can try below solution. I hope it ll help you.

array = ["","",nil,nil,2,3] array.delete_if(&:blank?) => [2,3]

0

If you also want to remove nil:

arr = ['',"",nil,323]
arr.map!{|x|x==''?nil:x}.compact!

=> [323]

Map, ternary operator, compact

xxjjnn
  • 14,591
  • 19
  • 61
  • 94
  • Unlike the other methods, this line evaluates as the returned array rather than what has been removed – xxjjnn Oct 10 '14 at 15:59
0

You can use .select! but you're still going to run into the same problem.

Instead of modifying array, you could create a utility class instead.

JSager
  • 1,420
  • 9
  • 18
0

For simple work around:

my_array = ['a', '', 2, 3, '']
compact_array = my_array.select(&:present?)
# => ["a", 2, 3]

Here:

We select only item of array that ruby think it's present while nil and "" is not present? in ruby

Radin Reth
  • 847
  • 8
  • 7
0

As of Rails 5.2, Enumerable now supports .compact_blank, which does precisely what you're asking for:

[1, "", nil, 2, " ", [], {}, false, true, 3].compact_blank
# =>  [1, 2, true, 3]

It works on hashes as well, removing pairs that have a blank value.

Docs: https://apidock.com/rails/Enumerable/compact_blank

David Hempy
  • 5,373
  • 2
  • 40
  • 68