class Comparator
def initialize(&default)
if (defined? default)
@compare_block=default
else
@compare_block=lambda { |a,b| a <=> b }
end
end
def compare(a,b)
@compare_block.call(a,b)
end
def to_proc
method(:compare).to_proc
end
def to_comparator
self
end
def then_by(next_aspect)
next_comparator=next_aspect.to_comparator
self.class.new do |a,b|
comparison=compare(a,b)
if (comparison == 0)
next_comparator.compare(a,b)
else
comparison
end
end
end
def reverse
self.class.new do |a,b|
comparison=compare(a,b)
if (comparison == 1)
-1
elsif (comparison == -1)
1
else
0
end
end
end
end
def by(aspect_to_compare)
aspect_to_compare.to_comparator
end
class Symbol
def to_comparator
Comparator.new { |a,b| a.send(self) <=> b.send(self) }
end
end
module Enumerable
def to_comparator
inject do |thus_far, every|
thus_far.to_comparator.then_by(every.to_comparator)
end
end
end
require 'rubyunit'
class SortTest < Test::Unit::TestCase
def test_simple
a=Person.new("blaine", 36)
b=Person.new("blaine", 12)
result=[a,b].sort(&by(:name).then_by(:age))
assert_equal([b,a], result)
end
def test_array
a=Person.new("blaine", 12)
b=Person.new("alice", 12)
result=[a,b].sort(&by([:age, :name]))
assert_equal([b,a], result)
end
def test_reverse
a=Person.new("grue", 123)
b=Person.new("thief", 34)
result=[a,b].sort(&by(:name).reverse)
assert_equal([b,a], result)
result=[a,b].sort(&by(:age).reverse)
assert_equal([a,b], result)
end
end
class Person
attr_reader :name, :age
def initialize(name, age)
@name=name
@age=age
end
end
I loved Neal's post, but it got me thinking that sometimes I need to sort beyond one field. How could I go about that? I whipped up this example really quick. The function :by is simply syntactic sugar for converting to a comparator. I thought it read better. Neal's solution is the way to go if you need to sort on a single field. But when you need more, the above will work too. This is another one of my little late night coding thoughts. Enjoy.
1 comment:
wow gold cheap wow gold buy wow gold world of warcraft gold wow world of warcraft wow gold WoW Warrior WoW Hunter WoW Rogue WoW Paladin WoW Shaman WoW Priest WoW Mage WoW Druid WoW Warlock power leveling powerleveling wow power leveling wow powerleveling wow guides wow tips google排名 google左侧排名 google排名服务 百度推广 百度排名 网站推广 商业吧 机床 LED灯 电池 塑料 摄像机 移民 甲醇 染料 福州热线 体育博客 股票博客 游戏博客 魔兽博客 考试博客 汽车博客 房产博客 电脑博客 powerlin518 logo design website design web design 商标设计
Post a Comment