I am looking for the most efficient way to do this. Anything with a hyphen must be in before any symbols without a hyphen in the array. My naive solution filters the array twice and concats. I feel like there should be a way to do this in one pass instead of two.
input = [:en, :de, :es, :"es-MX", :fr, :ko, :"ko-KR", :"en-GB"]
output = [:"es-MX", :"ko-KR", :"en-GB", :en, :de, :es, :fr]
Naive solution:
def reorder(input)
## find everything with a hypen
output = input.select { |l|
l.to_s.include?('-')
}
# find everything without a hyphen and concat to output
output.concat(input.reject { |l|
l.to_s.include?('-')
})
end
This is a sorting task, so it makes the most sense to me to simply use Enumerable#sort_by:
# Put symbols with hyphens first
input.sort_by { |s| s.to_s.include?('-') ? 0 : 1 }
If you want to sort by something else within those categories, you can do something like this:
# Put symbols with hyphens first, then sort in alphabetical order
input.sort_by { |s| [s.to_s.include?('-') ? 0 : 1, s] }
You can filter the array in one pass with Array#partition:
def reorder(input)
a, b = input.partition { |l| l.to_s.include?('-') }
a.concat(b)
end
input = [:en, :de, :es, :"es-MX", :fr, :ko, :"ko-KR", :"en-GB"]
code
p input.partition{|x|x.to_s.include?'-'}.flatten
Output
[:"es-MX", :"ko-KR", :"en-GB", :en, :de, :es, :fr, :ko]