tags:

views:

284

answers:

2

I would like to do the following but I don't think this will work:

.OrderByDescending(s => Score(s)), ...


private double Score(Story s)
        {
            DateTime now = DateTime.Now;
            TimeSpan elapsed = now.Subtract(s.PostedOn);
            double daysAgo = elapsed.TotalDays;

            return s.Votes.Count + s.Comments.Count - daysAgo;
        }

a. should this work? b. if not, do I need to query for the stories and then sort them by the score?

+3  A: 

Yes, that should work if the sequence is a sequence of Story items; what problem are you having? Note that if Score doesn't apply to any instance, it might be worth making it static.

Another option is to make the Score() method an instance method on a Story, or an extension method.

Note that this only applies to LINQ-to-Objects; if you are using LINQ-to-SQL / LINQ-to-Entities, etc you either need to use a lambda for the whole thing, or (in LINQ-to-SQL only) use a UDF-mapped function (on the data-context) to calculate the value.

Example (LINQ-to-Objects) with your original syntax:

using System.Linq;
using System;
class Story { // declare type
    public DateTime PostedOn { get; set; }
    // simplified purely for convenience
    public int VotesCount { get; set; }
    public int CommentsCount { get; set; }
}
static class Program {
    static void Main() {
        // dummy data
        var data = new[] {
            new Story { PostedOn = DateTime.Today,
                VotesCount = 1, CommentsCount = 2},
            new Story { PostedOn = DateTime.Today.AddDays(-1),
                VotesCount = 5, CommentsCount = 22},
            new Story { PostedOn = DateTime.Today.AddDays(-2),
                VotesCount = 2, CommentsCount = 0}
        };
        var ordered = data.OrderByDescending(s=>Score(s));
        foreach (var row in ordered)
        {
            Console.WriteLine(row.PostedOn);
        }
    }

    private static double Score(Story s) {
        DateTime now = DateTime.Now;
        TimeSpan elapsed = now.Subtract(s.PostedOn);
        double daysAgo = elapsed.TotalDays;
        // simplified purely for convenience
        return s.VotesCount + s.CommentsCount - daysAgo;
    }
}

Add a this (i.e. Score(this Story s)), and you can use:

.OrderByDescending(s=>s.Score())
Marc Gravell
+1  A: 

On a minor note, you may write

.OrderByDescending(Score)

since "Score"'s signature fulfills the required signature.

flq