tags:

views:

61

answers:

4

I want to split a string suppressing all null fields

Command:

",1,2,,3,4,,".split(',')

Result:

["", "1", "2", "", "3", "4", ""]

Expected:

["1", "2", "3", "4"]

How to do this?


Edit

Ok. Just to sum up all that good questions posted.

What I wanted is that split method (or other method) didn't generate empty strings. Looks like it isn't possible.

So, the solution is two step process: split string as usual, and then somehow delete empty strings from resulting array.

The second part is exactly this question (and its duplicate)

So I would use

",1,2,,3,4,,".split(',').delete_if(&:empty?) 

The solution proposed by Nikita Rybak and by user229426 is to use reject method. According to docs reject returns a new array. While delete_if method is more efficient since I don't want a copy. Using select proposed by Mark Byers even more inefficient.

steenslag proposed to replace commas with space and then use split by space:

",1,2,,3,4,,".gsub(',', ' ').split(' ')

Actually, the documentation says that space is actually a white space. But results of "split(/\s/)" and "split(' ')" are not the same. Why's that?

Mark Byers proposed another solution - just using regular expressions. Seems like this is what I need. But this solution implies that you have to be a master of regexp. But this is great solution! For example, if I need spaces to be separators as well as any non-alphanumeric symbol I can rewrite this to

",1,2, ,3 3,4 4 4,,".scan(/\w+[\s*\w*]*/)

the result is:

["1", "2", "3 3", "4 4 4"]

But again regexps are very unintuitive and they need an experience.

Summary

I expect that split to work with whitespaces as if whitespaces were a comma or even regexp. I expect it to do not produce empty strings. I think this is a bug in ruby or my misunderstanding.

Made it a community question.

+2  A: 

There's a reject method in array:

",1,2,,3,4,,".split(',').reject {|s| s.empty?}
Nikita Rybak
Vanuan
Matt Briggs
+1  A: 

You could use split followed by select:

",1,2,,3,4,,".split(',').select{|x|!x.empty?}

Or you could use a regular expression to match what you want to keep instead of splitting on the delimiter:

",1,2,,3,4,,".scan(/[^,]+/)
Mark Byers
A: 
",1,2,,3,4,,".split(/,/).reject(&:empty?)

",1,2,,3,,,4,,".squeeze(",").sub(/^,*|,*$/,"").split(",")
A: 

String#split(pattern) behaves as desired when pattern is a single space (ruby-doc).

",1,2,,3,4,,".gsub(',', ' ').split(' ')
steenslag
Hm... What if I want spaces to be included in substrings? (",1 2,,3 4,,") That won't work
Vanuan