ashisrai_
ashisrai_

Reputation: 6568

How do I remove blank elements from an array?

I have the following array

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]

I want to remove blank elements from the array and want the following result:

cities = ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Is there any method like compact that will do it without loops?

Upvotes: 346

Views: 280715

Answers (21)

phlegx
phlegx

Reputation: 2732

Most Explicit

cities.delete_if(&:blank?)

This will remove both nil values and empty string ("") values.

For example:

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal", nil]

cities.delete_if(&:blank?)
# => ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Rails 6.1+

Starting from version of Rails 6.1 ActiveSupport offers compact_blank.

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal", nil]

cities.compact_blank
# => ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Upvotes: 29

theabhisheksoni
theabhisheksoni

Reputation: 201

Update in reject and reject!

NOTE: I came across this question and checked these methods on the irb console with ruby-3.0.1. I also checked the ruby docs but this is not mentioned there. I am not sure from which ruby version this change is there. Any help from the community is much appreciated.

With ruby-3.0.1 we can use either reject or reject!

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]
cities.reject{ |e| e.empty? }
=> ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

or shorthand

cities.reject(&:empty?)
=> ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

both will return [] no matter we have an empty value or not?

enter image description here

Upvotes: 2

Marian13
Marian13

Reputation: 9228

compact_blank (Rails 6.1+)

If you are using Rails (or a standalone ActiveSupport), starting from version 6.1, there is a compact_blank method that removes blank values from arrays.

It uses Object#blank? under the hood for determining if an item is blank.

["Kathmandu", "Pokhara", "", "Dharan", nil, "Butwal"].compact_blank
# => ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

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

Here is a link to the docs and a link to the relative PR.

A destructive variant is also available. See Array#compact_blank!.


If you have an older version of Rails, check compact_blank internal implementation.

It is not so complex to backport it.

def compact_blank
  reject(&:blank?)
end

If you need to remove only nil values, consider using Ruby build-in Array#compact and Array#compact! methods.

["a", nil, "b", nil, "c", nil].compact
# => ["a", "b", "c"]

Upvotes: 69

vidur punj
vidur punj

Reputation: 5861

To remove nil values do:

 ['a', nil, 'b'].compact  ## o/p =>  ["a", "b"]

To remove empty strings:

   ['a', 'b', ''].select{ |a| !a.empty? } ## o/p => ["a", "b"]

To remove both nil and empty strings:

['a', nil, 'b', ''].select{ |a| a.present? }  ## o/p => ["a", "b"]

Upvotes: 11

Abel O'Ryan
Abel O'Ryan

Reputation: 4242

Plain Ruby:

values = [1,2,3, " ", "", "", nil] - ["", " ", nil]
puts values # [1,2,3]

Upvotes: 0

p4ndepravity
p4ndepravity

Reputation: 63

another method:

> ["a","b","c","","","f","g"].keep_if{|some| some.present?}
=> ["a","b","c","f","g"]

Upvotes: 0

Hieu Pham
Hieu Pham

Reputation: 6707

Update with a strict with join & split

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]
cities.join(' ').split

Result will be:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Note that: this doesn't work with a city with spaces

Upvotes: -3

kimerseen
kimerseen

Reputation: 2581

Here is what works for me:

[1, "", 2, "hello", nil].reject(&:blank?)

output:

[1, 2, "hello"]

Upvotes: 118

Javier Segovia
Javier Segovia

Reputation: 21

Shortest way cities.select(&:present?)

Upvotes: 2

Matt Greer
Matt Greer

Reputation: 62027

There are many ways to do this, one is reject

noEmptyCities = cities.reject { |c| c.empty? }

You can also use reject!, which will modify cities in place. It will either return cities as its return value if it rejected something, or nil if no rejections are made. That can be a gotcha if you're not careful (thanks to ninja08 for pointing this out in the comments).

Upvotes: 562

Sampat Badhe
Sampat Badhe

Reputation: 9075

Here is one more approach to achieve this

we can use presence with select

cities = ["Kathmandu", "Pokhara", "", "Dharan", nil, "Butwal"]

cities.select(&:presence)

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Upvotes: 10

esio
esio

Reputation: 1682

In my project I use delete:

cities.delete("")

Upvotes: 57

Naveed
Naveed

Reputation: 11167

There are already a lot of answers but here is another approach if you're in the Rails world:

 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].select &:present?

Upvotes: 12

anusha
anusha

Reputation: 2135

You can Try this

 cities.reject!(&:empty?)

Upvotes: 5

user2010324
user2010324

Reputation: 1889

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

=> ["A", "B", "C"]

Upvotes: 188

Francois
Francois

Reputation: 10631

Here is a solution if you have mixed types in your array:

[nil,"some string here","",4,3,2]

Solution:

[nil,"some string here","",4,3,2].compact.reject{|r| r.empty? if r.class == String}

Output:

=> ["some string here", 4, 3, 2]

Upvotes: 8

Colto
Colto

Reputation: 622

cities.reject! { |c| c.blank? }

The reason you want to use blank? over empty? is that blank recognizes nil, empty strings, and white space. For example:

cities = ["Kathmandu", "Pokhara", " ", nil, "", "Dharan", "Butwal"].reject { |c| c.blank? }

would still return:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

And calling empty? on " " will return false, which you probably want to be true.

Note: blank? is only accessible through Rails, Ruby only supports empty?.

Upvotes: 14

the Tin Man
the Tin Man

Reputation: 160551

Use reject:

>> cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].reject{ |e| e.empty? }
=> ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Upvotes: 20

superluminary
superluminary

Reputation: 49152

When I want to tidy up an array like this I use:

["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - ["", nil]

This will remove all blank or nil elements.

Upvotes: 46

Raels
Raels

Reputation: 400

Try this:

puts ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""]

Upvotes: 23

suren
suren

Reputation: 981

 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].delete_if {|c| c.empty? } 

Upvotes: 2

Related Questions