6

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.

2 Answers 2

7

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"]
Sign up to request clarification or add additional context in comments.

4 Comments

Don't forget sort_by which avoids the a/b thing.
One downside of the to_s approach is you get nonsense like 1, 11, 2, 20 and so on since they're sorted "ASCIIabetically". The partition approach is probably the best solution here.
Ups. Leaving just the partition way @3limin4t0r. As Cary has added something better with sort_by.
@SebastianPalma The other answer is also fine as long as you disclose it's boundaries. I'll remove my other comments since they are no longer relevant.
3
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.