0

I want this integer array to be sorted in the right order based on its number of occurrences.

question = [[1, 7, 8, 9, 10, 11, 12, 19, 20, 21, 31, 32, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 129, 132, 133, 134, 135, 136, 139], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 129, 130, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141], [30], [77]] 

question.flatten.uniq.size = 90

answer = sort_it(question)

answer = [77, 68, 8, 9, 10, 11, 12, 19, 20, 21, 31, 139, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 135, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 136, 66, 67, 7, 70, 71, 72, 73, 74, 75, 76, 1, 78, 79, 81, 129, 132, 133, 134, 45, 65, 32, 2, 3, 4, 5, 6, 13, 14, 15, 16, 17, 22, 23, 24, 25, 26, 27, 29, 33, 41, 69, 130, 137, 138, 140, 141, 30]

answer.uniq.size = 90

Here is my Ruby code:

def sort_it(actual)
        join=[]
        buffer = actual.dup 
        final = [ ]

                (actual.size-2).downto(0) {|j|
                join.unshift(actual.map{|i| i }.inject(:"&"))
                actual.pop
                }
        ordered_join =  join.reverse.flatten
        final << ordered_join
        final << buffer.flatten - ordered_join

        final.flatten
end

Is this approach OK? Is there a more efficient approach?

EDIT:

As a tribute to tokland and niklas, edited the answer which was in the wrong order before. Thanks!

12
  • What do you mean by "the right order based on its number of occurrences"? Can you say more explicitly what it is that you want the code to do? Commented May 1, 2012 at 12:46
  • Just out of curiosity, what's it for? Commented May 1, 2012 at 12:47
  • I don't get it. question is not an integer array? Commented May 1, 2012 at 12:48
  • @GarethMcCaughan : Now, I want to search for the set of books with the features, "fiction","hardcover","2011". I will have book_ids mapped to those features in a table and select them to form an array like [[1,2,3,4],[3,4,5,6],[4,9,8]]. So, book_id 4 is what the user is looking for. I want this array to be ordered as [4,3,1,2,5,6,9,8]. When I display my results in that order, user is happy. Do i make sense? Commented May 1, 2012 at 13:12
  • 1
    @beck: question is an array of integer arrays. Also, please include the desired output (because as tokland suggested, your answer doesn't make sense on first glance). In any case, from your description I think that Marc is spot-on with his answer. However, you should really solve this using a custom SQL query, your database is a lot faster than Ruby. Commented May 1, 2012 at 13:17

2 Answers 2

4

Use group_by:

question.flatten.group_by{|x| x}.sort_by{|k, v| -v.size}.map(&:first)
Sign up to request clarification or add additional context in comments.

2 Comments

@NiklasB. I was going to delete my solution! You were quicker to post... and quicker to delete!
But yours is nicer, as it doesn't involve a separate hash.
0

Answer with sort_by{|k, v| -v.size} calls v.size every time elements are compared. More effective solution:

question.flatten.group_by(&:to_i).map{|k,v| [k, -v.size]}.sort_by(&:last).map(&:first)

Though size of array is easy to get, it is unnecessary expense (O(sorting algorithm) instead of O(n)), and this idiom is good to remember anyway for more expensive operations

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.