开发者

Hacker News style ordering algorithm in Linq-To-SQL

开发者 https://www.devze.com 2022-12-20 05:33 出处:网络
According to this site the ordering algorithm for hacker news goes something like this: (p - 1) / (t + 2)^1.5

According to this site the ordering algorithm for hacker news goes something like this:

(p - 1) / (t + 2)^1.5

Description:

Votes divided by age factor

p = votes (points) from users. t = time since 开发者_如何转开发submission in hours.

p is subtracted by 1 to negate submitters vote. age factor is (time since submission in hours plus two) to the power of 1.5.

Given a table structure similar to this:

Item

ID

Link

DatePosted

Item_Votes

ItemID

Value

What would be the best way to implement the algorithm using linq to sql, would I be able to write the query entirely in linq or would I need to use a stored procedure or something else.

Update. Ended up using the code below based off TJB's answer:

    var votesQuery =
        from i in db.Items
        join v in db.Item_Votes on i.ItemID equals v.ItemID
        orderby
            (double)(v.Value - 1) /
                    Math.Pow(
                        (DateTime.Now - i.DatePosted.Value).TotalHours + 2,
                    1.5) descending
        select i;


Using 2 1 Linq queries (there's probably still a more efficent way)

var votesQuery =
    from i in items
    join v in votes on i.Id equals v.ItemId
    orderby
        (v.Value - 1) / 
                Math.Pow( 
                    (DateTime.Now - i.Posted).Add(new TimeSpan(2,0,0)).Hours, 
                1.5 )
    select new
    {
        Item = i,
        Vote = v
    };


Use a Comparer. This will allow you to write the logic for the comparisons between rows any way you want.

Here is an example, using case-insensitive ordering:

public void LinqExample()
{
    string[] words = { 
        "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" 
    };

    var sortedWords = words.OrderBy(a => a, new CaseInsensitiveComparer());

    ObjectDumper.Write(sortedWords);
}

public class CaseInsensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
    }
}

http://msdn.microsoft.com/en-us/vcsharp/aa336756.aspx


This might work (untested):

var orderedList = 
    from extracted in (
         from i in unorderedList 
             select new 
             { 
                 Item = i,
                 Order = (p - 1) / Math.Pow(t + 2, 1.5)
             }
             orderby extracted.Order
             select extracted.Item
         ).ToList();
0

精彩评论

暂无评论...
验证码 换一张
取 消