Help with sorting arrays with objects in it


#1

I have to build an array through both activerecord and also through a
ferret
index.

I was hoping to find a way of sorting the array as i combine the two so

def advanced_search(search_text, store, format, sortby)

find items in ferret index

items = Item.find_by_contents(search_text)

and now find all the items from a certain store or category

items_from_sql = Item.find_by_sql(“SELECT * …”)

@list = []
items.each do |i|
@list << i if items_from_sql.include?(i)
end

#now i need to sort @list somehow with sortby which would equal “title”
or
“price”
???
???

end

Any suggestions on helping me rethink this method


#2

On 6/1/06, Jake S. removed_email_address@domain.invalid wrote:

and now find all the items from a certain store or category

???

end

Hi Jake,

I’d do the whole thing through Ferret;

items = Item.find_by_contents(search_text, :sort => ["title", 

“price”])

I’m not sure what your SQL query is but I’m pretty sure it could be
handled in Ferret. Let’s say you wanted to get all times with the
subject of “Ruby” or “Rails”. Instead of;

items_from_sql =  Item.find_by_sql("SELECT * items WHERE subject =

‘Ruby’ OR subject = ‘Rails’")

You’d do this;

items = Item.find_by_contents(search_text + " +subject:(Ruby 

Rails)",
:sort => [“title”, “price”])

Or even better if speed is important, you could use a QueryFilter;

# first you'd create a FILTER constant
# NOTE: since we are creating the query directly we need to 

lowercase the
# terms which would usually be done by the QueryParser
bq = BooleanQuery.new()
bq.add_query(TermQuery.new(Term.new(“subject”, “ruby”),
BooleanClause::Occur::Should)
bq.add_query(TermQuery.new(Term.new(“subject”, “rails”),
BooleanClause::Occur::Should)
FILTER = QueryFilter.new(bq)

def advanced_search(search_text, store, format, sortby)

    items = Item.find_by_contents(search_text,
              :filter => FILTER,
              :sort => ["title", "price"])
    #...
end

Hope that helps. Of course sorting arrays is easy to.

@list.sort! do |a, b|
    cmp = (a.title <=> b.title)
    if cmp == 0
        cmp = (a.price <=> b.price)
    end
    next cmp
end

Cheers,
Dave


#3

@list.sort! do |a, b|
cmp = (a.title <=> b.title)
if cmp == 0
cmp = (a.price <=> b.price)
end
next cmp
end

One question though, if .title or .price are being passed in as a
string,
how do i use that?

i know this wont work, just trying to help explain

def sort_objects(objects,sortyby)
cmp = (a.sortby <=> b.sortby
if cmp == 0
cmp = (a.sortby <=> b.sortby)
end
next cmp
end

Thanks so much


#4

Thanks so much

jake


#5

If sortby is an array of strings;

def sort_objects(objects, sort_by)
    objects.sort! do |a,b|
        sort_by.each do |field|
            cmp = a.send(field) <=> b.send(field)
            break if cmp != 0
        end
        next cmp
    end
end

Something like this anyway. I didn’t bother testing it.


#6

Hi –

On Thu, 1 Jun 2006, Jake S. wrote:

i know this wont work, just trying to help explain

def sort_objects(objects,sortyby)
cmp = (a.sortby <=> b.sortby
if cmp == 0
cmp = (a.sortby <=> b.sortby)
end
next cmp
end

Does this help?

def sort_objects(objects,field)
objects.sort_by {|obj| obj.send(field) }
end

David

I was hoping to find a way of sorting the array as i combine the two so
items.each do |i|

# first you'd create a FILTER constant
def advanced_search(search_text, store, format, sortby)
    cmp = (a.title <=> b.title)

removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


David A. Black (removed_email_address@domain.invalid)