Sort a list of objects using their attributes in Ruby

I have a list of structures Fruitcalled basket. Each structure Fruithas name(a string) and calories(an integer). I would like to sort basketso that:

  • First displayed Fruitwith the highest calories. For example, a fruit with 500 calories appears in front of a fruit with 400 calories.

  • If two Fruithave equal calories, then Fruitwhose namecomes first in alphabetical order, first, ignoring case. For example, given two fruits with the same calories, one of them, called β€œbanana,” appears before it is called β€œCitrus.”

Definition Fruitis not something that I control, so I would prefer a solution that should not mix anything with Fruitor modify it. Is it possible?

+5
source share
4 answers

Easy solution

basket.sort_by { |f| [-f.calories, f.name] }

Of course, if this is the canonical sorting order for fruits, then it must be determined using the method <=>and with the module Comparablemixed inFruit

+11
source

Suppose your basket is an array or its subclass.

Quick way

Enumerable.sort_by

Gareth, Enumerable ( Array) sort_by, . , .

# -f.calories to sort descending
# name.downcase to do a case-insensitive sort
basket = basket.sort_by { |f| [-f.calories, f.name.downcase] }

Perl

Array.sort

Perl, <= > . . ! , . , , , , . - , Ruby StackOverflow.

baseket.sort! { |a,b|
  if a.calories == b.calories
    a.name.downcase <=> b.name.downcase
  else
    # Reverse the result to sort highest first.
    -(a.calories <=> b.calories)
  end
}
+2

. Array#sort (API doc). , -1, 0 1, Fruit, , , .

+1

, , , .

Spaceship-Operator (<=>) Comparable.

class Fruit
  attr_accessor :name, :color

  def <=>(other)
    # use Array#<=> to compare the attributes
    [self.name.downcase, self.color] <=> [other.name.downcase, other.color]
  end

  include Comparable
end

:

list_of_fruits.sort

(==, <, >) , , if (apple < banana) (. )

<=> Is returned for a refund -1if selfless other, +1if otherless, and 0if the two objects are equal.

+1
source

All Articles