class Foo
attr_reader :size, :color
def <=>
...
foo1 = Foo.new( size: 'large', color: 'blue' )
foo2 = Foo.new( size: 'small' )
foo3 = Foo.new( color: 'green' )
foo4 = Foo.new( size: 'small', color: 'red' )
...
尺寸订购小,零,中,大,超大。颜色为绿色,零色,蓝色,红色。
如何根据尺寸,然后按颜色有效排序?
答案 0 :(得分:2)
首先我明确声明订单:
@@size_order = {
'small' => 1,
'medium' => 2,
'large' => 3,
'super-sized' => 4
}
@@color_order = {
'green' => 1,
'blue' => 2,
'red' => 3
}
然后您可以按照以下方式确定<=>
方法:
def <=> ( o )
if (@size == o.size)
if (@color == o.color)
return 0
else
return (@@color_order[@color] > @@color_order[o.color]) ? 1 : -1
end
else
return (@@size_order[@size] > @@size_order[o.size]) ? 1 : -1
end
end
但是,使用两个类Foo
和Color
将Size
子类化为{em>更好(更多OOP)并定义<=>
对于他们每个人。
答案 1 :(得分:2)
class Foo
attr_reader :size, :color
VALID_COLORS = ["small",nil,"medium","large","super-sized"]
VALID_SIZES = ["green", nil, "blue", "red" ]
def size_pos
VALID_COLORS.index(size) || -1
end
def color_pos
VALID_SIZES.index(color) || -1
end
def initialize(opts={})
@size=opts[:size]
@color=opts[:color]
end
def <=>(other)
[size_pos,color_pos] <=> [other.size_pos, other.color_pos]
end
end
foo1 = Foo.new( size: 'large', color: 'blue' )
foo2 = Foo.new( size: 'small' )
foo3 = Foo.new( color: 'green' )
foo4 = Foo.new( size: 'small', color: 'red' )
[foo1,foo2,foo3,foo4].sort
#[#<Foo:0x000000020848d0 @size="small", @color=nil>,
#<Foo:0x00000002065700 @size="small", @color="red">,
#<Foo:0x00000002074868 @size=nil, @color="green">,
#<Foo:0x0000000208da98 @size="large", @color="blue"> ]
您可以通过将位置提取到类变量哈希或常量而不是每次调用索引来提高性能。
答案 2 :(得分:0)
假设'foos'是foo对象的集合:
foos.sort_by {|f| [ f.size || '', f.color || '' ]}
这可能比使用sort或定义&lt; =&gt;更有效。如果要调整排序顺序,则可以在属性为nil时使用空字符串以外的其他内容。为了提高灵活性,您可以执行以下操作:
def sort_by_size
foos.sort_by {|f| [ f.size || '', f.color || '' ]}
end
def sort_by_color
foos.sort_by {|f| [ f.color|| '', f.size|| '' ]}
end