W Davison W Davison - 1 month ago 4
C# Question

Removing Items From List with Parameter of Matching String most Recent DateTime

I am trying to narrow down a list which is comprised of all files with matching product ID (eg M320.1215). When I say I need to narrow it down I want to remove the list entries in order to keep only the most recent items in the list.

This is an example of a file name: I_ATTRIBUTES_M320.1215_EGHS_CS_07112016225939.xlsx

Here you see the Product Id as "M320.1215"
The Subformat and Language "EGHS_CS"
And a date and time 07112016225939 in format MMDDYYYYHHMMSS. I can get the date time into DateTime object using:

public DateTime correctedDateString(string dts)
{
string correctDTS = dts.Insert(2, "/");
correctDTS = correctDTS.Insert(5, "/");
correctDTS = correctDTS.Insert(10, " ");
correctDTS = correctDTS.Insert(13, ":");
correctDTS = correctDTS.Insert(16, ":");
DateTime convertedDate = DateTime.Now;
try
{
convertedDate = Convert.ToDateTime(correctDTS);
Console.WriteLine("'{0}' converts to {1} {2} time.", correctDTS, convertedDate, convertedDate.Kind.ToString());
}
catch (FormatException)
{
convertedDate = Convert.ToDateTime("01/01/2015 00:00:00");
Console.WriteLine("'{0}' is not in the proper format.", correctDTS);
}
return convertedDate;


This obviously a simple method.
I have been using the following to split the items in the list into usable segments:

string[] tempArray = Path.GetFileNameWithoutExtension(filenames[i].ToString()).ToString().Split(new[] { "_" }, StringSplitOptions.None);


Now what I am struggling with is to manipulate the following list to only keep the most recent versions of each subFormat and language combo.

List<string> filenames = new List<string>()
{
"I_ATTRIBUTES_M320.1215_EGHS_RU_07132016020215",
"I_ATTRIBUTES_M320.1215_EGHS_BE_06292016132122",
"I_ATTRIBUTES_M320.1215_EGHS_BE_06302016100039",
"I_ATTRIBUTES_M320.1215_EGHS_BE_07042016080530",
"I_ATTRIBUTES_M320.1215_EGHS_BE_07112016225936",
"I_ATTRIBUTES_M320.1215_EGHS_BE_07132016020203",
"I_ATTRIBUTES_M320.1215_EGHS_BR_06292016132127",
"I_ATTRIBUTES_M320.1215_EGHS_BR_06302016100042",
"I_ATTRIBUTES_M320.1215_EGHS_BR_07042016080536",
"I_ATTRIBUTES_M320.1215_EGHS_BR_07112016225938",
"I_ATTRIBUTES_M320.1215_EGHS_BR_07132016020206",
"I_ATTRIBUTES_M320.1215_EGHS_CS_07112016225939",
"I_ATTRIBUTES_M320.1215_EGHS_CS_07132016020207",
"I_ATTRIBUTES_M320.1215_EGHS_DE_06292016132128",
"I_ATTRIBUTES_M320.1215_EGHS_DE_06302016100044",
"I_ATTRIBUTES_M320.1215_EGHS_DE_07042016080537",
"I_ATTRIBUTES_M320.1215_EGHS_DE_07112016225940",
"I_ATTRIBUTES_M320.1215_EGHS_DE_07132016020208",
"I_ATTRIBUTES_M320.1215_EGHS_FR_06292016132129",
"I_ATTRIBUTES_M320.1215_EGHS_FR_06302016100045",
"I_ATTRIBUTES_M320.1215_EGHS_FR_07042016080538",
"I_ATTRIBUTES_M320.1215_EGHS_FR_07112016225941",
"I_ATTRIBUTES_M320.1215_EGHS_FR_07132016020210",
"I_ATTRIBUTES_M320.1215_EGHS_IT_06292016132129",
"I_ATTRIBUTES_M320.1215_EGHS_IT_06302016100046",
"I_ATTRIBUTES_M320.1215_EGHS_IT_07042016080539",
"I_ATTRIBUTES_M320.1215_EGHS_IT_07112016225941",
"I_ATTRIBUTES_M320.1215_EGHS_IT_07132016020211",
"I_ATTRIBUTES_M320.1215_EGHS_MS_06292016132130",
"I_ATTRIBUTES_M320.1215_EGHS_MS_06302016100047",
"I_ATTRIBUTES_M320.1215_EGHS_MS_07042016080540",
"I_ATTRIBUTES_M320.1215_EGHS_MS_07112016225943",
"I_ATTRIBUTES_M320.1215_EGHS_MS_07132016020212",
"I_ATTRIBUTES_M320.1215_EGHS_PL_06292016132131",
"I_ATTRIBUTES_M320.1215_EGHS_PL_06302016100048",
"I_ATTRIBUTES_M320.1215_EGHS_PL_07042016080541",
"I_ATTRIBUTES_M320.1215_EGHS_PL_07112016225944",
"I_ATTRIBUTES_M320.1215_EGHS_PL_07132016020214",
"I_ATTRIBUTES_M320.1215_EGHS_RU_06292016132131",
"I_ATTRIBUTES_M320.1215_EGHS_RU_06302016100049",
"I_ATTRIBUTES_M320.1215_EGHS_RU_07042016080542",
"I_ATTRIBUTES_M320.1215_EGHS_RU_07112016225945"
};


So essentially I need the final list to be as follows:

List<string> filenames = new List<string>()
{
"I_ATTRIBUTES_M320.1215_EGHS_BE_07132016020203",
"I_ATTRIBUTES_M320.1215_EGHS_BR_07132016020206",
"I_ATTRIBUTES_M320.1215_EGHS_CS_07132016020207",
"I_ATTRIBUTES_M320.1215_EGHS_DE_07132016020208",
"I_ATTRIBUTES_M320.1215_EGHS_FR_07132016020210",
"I_ATTRIBUTES_M320.1215_EGHS_IT_07132016020211",
"I_ATTRIBUTES_M320.1215_EGHS_MS_07132016020212",
"I_ATTRIBUTES_M320.1215_EGHS_PL_07132016020214",
"I_ATTRIBUTES_M320.1215_EGHS_RU_07132016020215"
};


Thank you in advance for any help.

Answer

You could do this with Linq

var grouped = filenames.Select(x => x.Split('_'))
    .GroupBy(x => x[2] + x[3] + x[4], p => p, (key, g) => new { Id = key, Items = g.ToList() })
    .Select(x => x.Items.OrderByDescending(i => correctedDateString(i[5])).FirstOrDefault())
    .Select(x => string.Join("_", x))
    .ToList();