This will do it succinctly for you:
var inFiles = new List<string>
{
"Report 1 2017-08-01.xls",
"Report 1 2017-08-09.xls",
"Report 1 2017-08-27.xls",
"Report 1 2017-09-01.xls",
"Report 1 2017-09-09.xls",
"Report 1 2017-09-18.xls",
"Report 2 2017-08-01.xls",
"Report 2 2017-08-09.xls",
"Report 2 2017-08-27.xls",
"Report 2 2017-09-01.xls",
"Report 2 2017-09-09.xls",
"Report 2 2017-09-22.xls",
"Report 3 2017-08-01 blabla.xls",
"Report 3 2017-08-09 blabla.xls",
"Report 3 2017-08-27 blabla.xls",
"Report 3 2017-09-01 blabla.xls",
"Report 3 2017-09-09 blabla.xls",
"Report 3 2017-09-30 blabla.xls"
};
var deleteFiles = inFiles.Select(x => new { date = DateTime.Parse(Regex.Match(x, @"\d{4}-\d{2}-\d{2}").Value), file = x })
.Select(x => new { id = x.file.Replace(x.date.ToString("yyyy-MM-dd"), ""), date = x.date, file = x.file })
.OrderByDescending(x => x.date)
.GroupBy(x => x.id)
.SelectMany(x => x.Skip(1).Select(y => y.file));
foreach (var file in deleteFiles)
{
Console.WriteLine(file);
}
Outputs:
Report 3 2017-09-09 blabla.xls
Report 3 2017-09-01 blabla.xls
Report 3 2017-08-27 blabla.xls
Report 3 2017-08-09 blabla.xls
Report 3 2017-08-01 blabla.xls
Report 2 2017-09-09.xls
Report 2 2017-09-01.xls
Report 2 2017-08-27.xls
Report 2 2017-08-09.xls
Report 2 2017-08-01.xls
Report 1 2017-09-09.xls
Report 1 2017-09-01.xls
Report 1 2017-08-27.xls
Report 1 2017-08-09.xls
Report 1 2017-08-01.xls
UPDATE
To keep the most recent of each month, we need to expand the grouping to also include year and month. This will create more groups which is what we want:
var deleteFiles =
inFiles.Select(x => new
{
date = DateTime.Parse(Regex.Match(x, @"\d{4}-\d{2}-\d{2}").Value),
file = x
})
.Select(x => new
{
id = x.file.Replace(x.date.ToString("yyyy-MM-dd"), ""),
year = x.date.Year,
month = x.date.Month,
date = x.date,
file = x.file
})
.OrderByDescending(x => x.date)
.GroupBy(x => new { id = x.id, year = x.year, month = x.month })
.SelectMany(x => x.Skip(1).Select(y => y.file));
Now the output is:
Report 3 2017-09-09 blabla.xls
Report 3 2017-09-01 blabla.xls
Report 2 2017-09-09.xls
Report 2 2017-09-01.xls
Report 1 2017-09-09.xls
Report 1 2017-09-01.xls
Report 1 2017-08-09.xls
Report 1 2017-08-01.xls
Report 2 2017-08-09.xls
Report 2 2017-08-01.xls
Report 3 2017-08-09 blabla.xls
Report 3 2017-08-01 blabla.xls
Here is a bonus piece of code for you... It will tell you which files are being kept:
Console.WriteLine("-- Keeping:");
foreach (var file in inFiles.Except(deleteFiles))
{
Console.WriteLine(file);
}
Which outputs:
-- Keeping:
Report 1 2017-08-27.xls
Report 1 2017-09-18.xls
Report 2 2017-08-27.xls
Report 2 2017-09-22.xls
Report 3 2017-08-27 blabla.xls
Report 3 2017-09-30 blabla.xls