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 DatePostedItem_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();
精彩评论