Reputation: 1332
Input :
arr = [4,2,'b',5,'c','a',7]
Output:
[2,4,5,7,'a','b','c']
I can think of this :
int_arr = arr.select {|x| x.instance_of?(Integer)}.sort
str_arr = arr.select {|x| x.instance_of?(String)}.sort
int_arr + str_arr
Please suggest a efficient way to do it.
Upvotes: 6
Views: 853
Reputation: 110685
arr.sort_by { |e| [e.is_a?(Integer) ? 0 : 1, e] }
#=> [2, 4, 5, 7, "a", "b", "c"]
[22, 'efg', 0, 'abc', -4].sort_by { |e| [e.is_a?(Integer) ? 0 : 1, e] }
#=> [-4, 0, 22, "abc", "efg"]
See Enumerable#sort_by. sort_by
performs pair-wise comparisons of 2-element arrays using the method Array#<=>. See especially the third paragraph of that doc.
The following could be used if, as in the example, the integers are single digits and the strings are single characters.
arr.sort_by(&:ord)
#=> [2, 4, 5, 7, "a", "b", "c"]
See Integer#ord and String#ord.
Upvotes: 3
Reputation: 33430
One way is to partition
your array by those elements being Integer, to make sure they remain first and then sort the elements of each array:
[4,2,'b',5,'c','a',7].partition { |e| e.is_a?(Integer) }.flat_map(&:sort)
# [2, 4, 5, 7, "a", "b", "c"]
Upvotes: 7