Alex Gordon
Alex Gordon

Reputation: 60912

c# getting last element in LINQ statement

    var filePaths = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv").Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) })
        .OrderBy(x => x.Date)
        .Where(x => x.Date >= LastCreatedDate);

i would like to know the value of the most recent x.Date

from this linq statement how can i get the most recent date?

please note that i do not need the filepath rather i need the DATE

Upvotes: 1

Views: 1493

Answers (6)

spender
spender

Reputation: 120548

As you're using LinqToObjects, if performance is a consideration, you should perhaps consider implementing a MaxBy type method, instead of using OrderBy combined with FirstOrDefault.

I'll find you an implementation. [no need... see @phoog's answer]

Upvotes: 1

phoog
phoog

Reputation: 43076

F# has a handy MaxBy() function that I like to use; the C# implementation is trivial. It allows you to avoid the cost of sorting the sequence.

See this answer for more detail: https://stackoverflow.com/a/8759648/385844

usage:

var mostRecent = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv")  
    .Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) })   
    .Where(x => x.Date >= LastCreatedDate)  
    .MaxBy(x => x.Date);

Upvotes: 2

Paul Sasik
Paul Sasik

Reputation: 81557

Try this:

        var filePaths = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv")
            .Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) })
            .OrderByDescending(x => x.Date)
            .Where(x => x.Date >= LastCreatedDate)
            .FirstOrDefault();

The changes to your statement are the sorting (OrderByDescending instead of OrderBy) to put the newest date "on top" and FirstOrDefault which will select the top, single item from the collection and should result in null if the collection is empty.

To get more file properties you could modify your anonymous object to include more properties, thusly:

        var filePath = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv")
            .Select(p => new { Path = p, Date = File.GetLastWriteTime(p), CreatedDate = File.GetCreationTime(p) })
            .OrderByDescending(x => x.Date)
            .Where(x => x.Date >= DateTime.Now)
            .FirstOrDefault();

        Console.WriteLine(filePath.Date);
        Console.WriteLine(filePath.Path);
        Console.WriteLine(filePath.CreatedDate);

Or more succinctly (no need for an anonymous object) you could do this:

        var filePath = new DirectoryInfo(@"\\Pontos\completed\").GetFiles("*_*.csv")
            .Select(p => p)
            .OrderByDescending(p => p.CreationTime)
            .Where(x => x.CreationTime >= DateTime.Now)
            .FirstOrDefault();

        Console.WriteLine(filePath.CreationTime);
        Console.WriteLine(filePath.FullName);

Upvotes: 1

BrokenGlass
BrokenGlass

Reputation: 161012

Just reverse the order - also do the filtering before the ordering:

 var filePaths = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv").Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) })
        .Where(x => x.Date >= LastCreatedDate)
        .OrderByDescending(x => x.Date)
        .FirstOrDefault();

Instead I would suggest you use DirectoryInfo's GetFiles() instead which returns FileInfo instances so you don't have to grab the last write time manually:

var di = new DirectoryInfo(@"\\Pontos\completed\");
var file =  di.GetFiles("*_*.csv")
              .Where(f=> f.LastWriteTimeUtc >= LastCreatedDate)
              .OrderByDescending(f => f.LastWriteTimeUtc)
              .FirstOrDefault();


if(file!=null)
{
   Console.WriteLine("Path: {0}, Last Write Time: {1}", file.FullName, 
                                                        file.LastWriteTimeUtc);
}

Upvotes: 4

mindandmedia
mindandmedia

Reputation: 6825

you can use the method .Take(1);

Upvotes: 1

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93484

var mostRecent = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv")
    .Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) }) 
    .OrderBy(x => x.Date) 
    .Where(x => x.Date >= LastCreatedDate)
    .LastOrDefault(); 

or

var mostRecent = Directory.GetFiles(@"\\Pontos\completed\", "*_*.csv")
    .Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) }) 
    .OrderByDescending(x => x.Date) 
    .Where(x => x.Date >= LastCreatedDate)
    .FirstOrDefault(); 

Upvotes: 7

Related Questions