实现OrderBy / ThenBy的智能方法是什么?

时间:2009-03-02 02:14:26

标签: linq algorithm language-agnostic

我在Lua中实现了一个LINQ克隆,但这里并没有太多相关性,而且我已经完成了大部分功能(可枚举/可查询,而不是预编译器),但无法想到一种智能的实现方式OrderBy的ThenBy。

目前我排序一次,然后放入新的列表,然后对这些子列表进行排序,最后再次合并结果,但这看起来非常浪费和不优雅,我敢肯定有人已经想出了一个聪明的方法来做到这一点(更好算法),但我不知道它是什么。关于如何以有效的方式实现OrderBy / Thenby的任何线索?

注意:语言和语言结构在这里是不相关的,我正在寻找广义算法,就像说二进制排序可以用任何语言完成。

编辑:目前我正在研究LINQ to Object,所以任何想法如何做到特别好。我猜OrberBy / ThenBy是2个函数调用,不是一个,但我可能错了。

2 个答案:

答案 0 :(得分:3)

通常,您将使用合适的比较方法实现多键排序。例如,要按姓氏和名字对名称列表进行排序,您可以使用这样的比较函数:

int compareNames(Name n1, Name n2)
{
    if (n1.LastName < n2.LastName) {
        return -1;
    } else if (n1.LastName > n2.LastName) {
        return 1;
    } else if (n1.FirstName < n2.FirstName) {
        return -1;
    } else if (n1.FirstName > n2.FirstName) {
        return 1;
    } else {
        return 0;
    }
}

这里的关键点是,除非我们已经知道两个FirstName成员相等,否则我们不会查看LastName成员。

答案 1 :(得分:1)

我认为这也有效:

function(lh,rh)
    if lh.first < rh.first then
        return true
    elseif lh.second < rh.second then
        return true
    end
    return false
end

如果为真,则表示这应该有效:

tests={}
tests[1]=function(lh,rh) 
    return lh.first < rh.first
end
tests[2]=function(lh,rh)
    return lh.second < rh.second
end

function(lh,rh)
    local res=true
    local k,v
    for k,v in ipairs(tests) do
        res = v(lh,rh)
        if res then break end
    end
    return res
end