Reputation: 43
I have a simple but yet very hard task for my coding skills.
Basically I have a task to parse all file names in specific folder (this executed ok) but then I have to compare those file names and choose the one with the latest (biggest) number in a specific part of file name. An example:
0074-105-NVK.1.p7.ver.1.pdf
0074-105-NVK.1.p7.ver.2.pdf
0074-105-NVK.1.p7.ver.3.pdf
The part that interests me is the one where "ver.1" from this the program should choose the highest one and remove other files. And I really don't know how to implement this filename comparison.
Upvotes: 2
Views: 510
Reputation: 214
It can be done nicely with a single lambda row:
var s1 = "0074-105-NVK.1.p7.ver.1.pdf";
var s2 = "0074-105-NVK.1.p7.ver.2.pdf";
var s3 = "0074-105-NVK.1.p7.ver.3.pdf";
var arr = new[] {s1, s2, s3};
var latestVer = arr.OrderBy(s => int.Parse(s.Split('.')[s.Split('.').Length - 2])).Last();
Upvotes: 1
Reputation: 273
Try this code:
string[] files = new string[] {
"0074 - 105 - NVK.1.p7.ver.1.pdf",
"0074 - 105 - NVK.1.p7.ver.11.pdf",
"0074 - 105 - NVK.1.p7.ver.2.pdf", };
var result = files.Select(f => new
{
name = f,
ver = int.Parse((f.Substring(f.IndexOf(".ver") + 1).Split('.')[1]))
})
.OrderByDescending(x => x.ver)
.Select(x => x.name)
.FirstOrDefault();
Upvotes: 0
Reputation: 1336
You could use the following to get all file names as:
string[] fileNames = Directory.GetFiles(@"d:\Dir\", "*.pdf").ToList();
List<string> nameOnly = new List<string>();
List<KeyValuePair<string, string>> bind = new List<KeyValuePair<string, string>>();
once you have all the file names in a list then you can exclude the extension as:
foreach(var item in fileNames)
{
var x = Regex.Match(item, @".*(?=\.)").Value;
nameOnly.Add(x);
}
Just for binding each name with its file name:
foreach(var item in nameOnly)
{
var x = Regex.Match(item, @".*(?=\.)").Value;
bind.Add(new KeyValuePair<string, string>(x,item));
}
And you can get the final file name with max number as:
var max = bind.OrderBy(x => x.Key);
var fileName = max.LastOrDefault().Value;
Upvotes: 1
Reputation: 186678
I suggest extracting version info with a help of regular expressions and ordering by this version:
string[] files = new string[] {
"0074 - 105 - NVK.1.p7.ver.1.pdf",
"0074 - 105 - NVK.1.p7.ver.2.pdf",
"0074 - 105 - NVK.1.p7.ver.3.pdf", };
string pattern = @"ver\.(?<version>[0-9]+(\.[0-9]+)*)[^0-9]+$";
var result = files
.Select(file => new {
name = file,
ver = new Version(Regex.Match(file, pattern).Groups["version"].Value + ".0")
})
.OrderByDescending(item => item.ver)
.Select(item => item.name)
.FirstOrDefault();
Upvotes: 5
Reputation: 326
You should have filenames in array or list:
var fileNames = new List<string>();
// fill list with proper file names
Regading you sample you can sort this list (assume that only ver.x can change):
list.Sort(); // you can use parametrized method which sort by part of string
You can also use SortedList (that you have all sorted automatically):
var fileNames = new SortedList<string>();
fileNames.Add(fileName.Substring(18), fileName);
Or you can use Linq:
var sorted = fileNames.OrderBy(item => item.Substring(18)); // in that case you can use different parts of file name)
Upvotes: 0