Use filename to determine file type
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
This is legacy, so I'm not really looking for improvements on architectural approach.
Here's what the method does:
- Extracts filename from a string containing full file path (passed in as parameter)
- Checks to see if the filename extracted is not null or empty or just white spaces
If check in step 2 passes, then it uses naming conventions in the filename, to determine the logical "Type" for the file as follows:
- If filename contains
__Import__
, then setType
toSource Data
- If filename contains
__Export__
, then setType
toDestination Data
- If filename contains
__Transform__
, then setType
toTransformational Data
- If none of the conditions from 3.1 through 3.3 are met, then default the "Type" to
General
.
- If filename contains
Is there a way to make the if...else if... else if...
block more concise, and elegant without loss of functionality?
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
// if filename is not empty
if (!string.IsNullOrWhiteSpace(fileName))
// if... else... to determine type of file contents based on file name convention
// legacy code, so not looking for architectural improvements etc... :)
if (fileName.Contains("__Import__"))
fileDataType = "Source Data";
else if (fileName.Contains("__Export__"))
fileDataType = "Destination Data";
else if (fileName.Contains("__Transform__"))
fileDataType = "Transformational Data";
else
fileDataType = "General";
return fileDataType;
c# strings
add a comment |Â
up vote
4
down vote
favorite
This is legacy, so I'm not really looking for improvements on architectural approach.
Here's what the method does:
- Extracts filename from a string containing full file path (passed in as parameter)
- Checks to see if the filename extracted is not null or empty or just white spaces
If check in step 2 passes, then it uses naming conventions in the filename, to determine the logical "Type" for the file as follows:
- If filename contains
__Import__
, then setType
toSource Data
- If filename contains
__Export__
, then setType
toDestination Data
- If filename contains
__Transform__
, then setType
toTransformational Data
- If none of the conditions from 3.1 through 3.3 are met, then default the "Type" to
General
.
- If filename contains
Is there a way to make the if...else if... else if...
block more concise, and elegant without loss of functionality?
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
// if filename is not empty
if (!string.IsNullOrWhiteSpace(fileName))
// if... else... to determine type of file contents based on file name convention
// legacy code, so not looking for architectural improvements etc... :)
if (fileName.Contains("__Import__"))
fileDataType = "Source Data";
else if (fileName.Contains("__Export__"))
fileDataType = "Destination Data";
else if (fileName.Contains("__Transform__"))
fileDataType = "Transformational Data";
else
fileDataType = "General";
return fileDataType;
c# strings
1
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
2
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
This is legacy, so I'm not really looking for improvements on architectural approach.
Here's what the method does:
- Extracts filename from a string containing full file path (passed in as parameter)
- Checks to see if the filename extracted is not null or empty or just white spaces
If check in step 2 passes, then it uses naming conventions in the filename, to determine the logical "Type" for the file as follows:
- If filename contains
__Import__
, then setType
toSource Data
- If filename contains
__Export__
, then setType
toDestination Data
- If filename contains
__Transform__
, then setType
toTransformational Data
- If none of the conditions from 3.1 through 3.3 are met, then default the "Type" to
General
.
- If filename contains
Is there a way to make the if...else if... else if...
block more concise, and elegant without loss of functionality?
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
// if filename is not empty
if (!string.IsNullOrWhiteSpace(fileName))
// if... else... to determine type of file contents based on file name convention
// legacy code, so not looking for architectural improvements etc... :)
if (fileName.Contains("__Import__"))
fileDataType = "Source Data";
else if (fileName.Contains("__Export__"))
fileDataType = "Destination Data";
else if (fileName.Contains("__Transform__"))
fileDataType = "Transformational Data";
else
fileDataType = "General";
return fileDataType;
c# strings
This is legacy, so I'm not really looking for improvements on architectural approach.
Here's what the method does:
- Extracts filename from a string containing full file path (passed in as parameter)
- Checks to see if the filename extracted is not null or empty or just white spaces
If check in step 2 passes, then it uses naming conventions in the filename, to determine the logical "Type" for the file as follows:
- If filename contains
__Import__
, then setType
toSource Data
- If filename contains
__Export__
, then setType
toDestination Data
- If filename contains
__Transform__
, then setType
toTransformational Data
- If none of the conditions from 3.1 through 3.3 are met, then default the "Type" to
General
.
- If filename contains
Is there a way to make the if...else if... else if...
block more concise, and elegant without loss of functionality?
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
// if filename is not empty
if (!string.IsNullOrWhiteSpace(fileName))
// if... else... to determine type of file contents based on file name convention
// legacy code, so not looking for architectural improvements etc... :)
if (fileName.Contains("__Import__"))
fileDataType = "Source Data";
else if (fileName.Contains("__Export__"))
fileDataType = "Destination Data";
else if (fileName.Contains("__Transform__"))
fileDataType = "Transformational Data";
else
fileDataType = "General";
return fileDataType;
c# strings
edited Aug 2 at 4:58
Jamalâ¦
30.1k11114225
30.1k11114225
asked Aug 1 at 17:09
Shiva
1244
1244
1
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
2
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57
add a comment |Â
1
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
2
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57
1
1
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
2
2
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
5
down vote
I find the cleanest way is to replace the ugly if/else if/else
with a dictionary:
private static IDictionary<string, string> FileDataTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
["Import"] = "Source Data",
// ..
The also not so pretty Contains
can be replaced with a nice regex that will grow or shirnk automatically if you add/remove mappings:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileContentsMatch = Regex.Match(fileName, $"__(?<Type>", FileDataTypes.Keys))__", RegexOptions.ExplicitCapture
Notice that both the dictionary and the regex are case insensitive. You should always make paths case insensitive in Windows. You are lucky that this worked for so long.
(Dislaimer: It's just an example so I was to lazy to implement all the empty/null checks)
add a comment |Â
up vote
2
down vote
You're searching through the file name for each type until you find one. If you use the __
as delimiters and find the indexes of the string between them, you will only search the whole string once.
By extracting the substring with the type, now you can use a switch
block to return the appropriate value:
private static string GetFileDataType(string fullFileNameWithPath)
const string Delimiter = "__";
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
int indexA = fileName.IndexOf(Delimiter);
string type = "";
if(indexA != -1 && indexA != 0)
indexA += 2;
int indexB = fileName.IndexOf(Delimiter, indexA);
if(indexB != -1)
type = fileName.Substring(indexA, indexB - indexA);
switch(type)
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
default:
return "General";
If the string is empty or malformed "General" will be returned. Because the check for this is in one place it can easily be changed, if desired.
You can just use.Trim('_')
to remove the leading and trailing underscores ;-)
â t3chb0t
Aug 1 at 18:53
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named groupType
.
â t3chb0t
Aug 1 at 19:57
2
This doesn't produce the same result like the original code. For__Transform__SomeMoreText
it returns "General", fornull
it throws an exception, forstring.Empty
it returns "General" instead ofstring.empty
, for__Some__Export__SomeMoreText
it returns "General" instead ofDestination Data
â Heslacher
Aug 2 at 5:45
 |Â
show 3 more comments
up vote
2
down vote
The method you have provided looks clean, is short and is easy to understand. It does what it should do but calls Contains()
in the worst case 3 times which could be avoided.
A filedatatype other than General
can only happen if at least the delimiter __
is found twice. So why don't we Split()
the filname and if we get an array which length is at least 3
we have something to work with.
Let us assume the filename without extension reads SomeFile__Export__SomeMoreText
if we call Split()
using __
as splitting argument we would get "SomeFile", "Export", "SomeMoreText"
now we can easily iterate over the array starting at the second element and ending at the element before last and using a switch
on each element to gain the desired filedatatype.
Overall this would look like
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;
var possibleFileDataTypes = fileName.Split(new string "__" , StringSplitOptions.None);
if (possibleFileDataTypes.Length < 3) return "General";
for (var i = 1; i < possibleFileDataTypes.Length - 1; i++)
switch (possibleFileDataTypes[i])
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
return "General";
and produces the following results
GetFileDataType(string.Empty) -> string.Emtpty
GetFileDataType(null) -> string.Emtpty
GetFileDataType(@"C:folderText__Export__SomeOtherText.txt") -> "Destination Data"
GetFileDataType(@"C:folderText__SomeOtherText__SomeMoreText.txt") -> "General"
GetFileDataType(@"C:folderSome__File__Import__Some__More__Text.txt") -> "Source Data"
GetFileDataType(@"C:folder__Transform__Some__More__Text.txt") -> "Transformational Data"
GetFileDataType(@"C:folder__Export__.txt") -> "Destination Data"
GetFileDataType(@"C:folder__Export.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
add a comment |Â
up vote
0
down vote
A different approach based on the idea to use something like a dictonary (t3chb0t's answer) is using two arrays of strings internally. One to check if this "string-component" is present in the file name, the other one to return the file type.
Using these two you need to iterate the first array and return from the second array using same index if you find something.
This removes the if/else structure and seems to be easy to read to me, eventough (or maybe because) it is not as advanced as the other answers and keeps the contains().
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName))
return string.Empty;
String fileNameComponents = "__Import__", "__Export__", "__Transform__" ;
String fileTypes = "Source Data", "Destination Data", "Transformational Data" ;
for (int i = 0; i < fileNameComponents.Length; i++)
if (fileName.Contains(fileNameComponents[i]))
return fileTypes[i];
return "General";
This approach only aims at the core of the question (removing the if/else) whitout considering any improvments to performance.
add a comment |Â
up vote
0
down vote
Composing with a list of functions, one can drastically reduce the number of needed lines:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
return matchingRules.First(tuple => tuple.Item1(fileName)).Item2;
With matchingRules
declared as follow:
var matchingRules = new List<(Func<string, bool>, string)>();
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Import__"), "Source Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Export__"), "Destination Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Transform__"), "Transformational Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f), "General"));
matchingRules.Add((f => true, string.Empty));
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
I find the cleanest way is to replace the ugly if/else if/else
with a dictionary:
private static IDictionary<string, string> FileDataTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
["Import"] = "Source Data",
// ..
The also not so pretty Contains
can be replaced with a nice regex that will grow or shirnk automatically if you add/remove mappings:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileContentsMatch = Regex.Match(fileName, $"__(?<Type>", FileDataTypes.Keys))__", RegexOptions.ExplicitCapture
Notice that both the dictionary and the regex are case insensitive. You should always make paths case insensitive in Windows. You are lucky that this worked for so long.
(Dislaimer: It's just an example so I was to lazy to implement all the empty/null checks)
add a comment |Â
up vote
5
down vote
I find the cleanest way is to replace the ugly if/else if/else
with a dictionary:
private static IDictionary<string, string> FileDataTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
["Import"] = "Source Data",
// ..
The also not so pretty Contains
can be replaced with a nice regex that will grow or shirnk automatically if you add/remove mappings:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileContentsMatch = Regex.Match(fileName, $"__(?<Type>", FileDataTypes.Keys))__", RegexOptions.ExplicitCapture
Notice that both the dictionary and the regex are case insensitive. You should always make paths case insensitive in Windows. You are lucky that this worked for so long.
(Dislaimer: It's just an example so I was to lazy to implement all the empty/null checks)
add a comment |Â
up vote
5
down vote
up vote
5
down vote
I find the cleanest way is to replace the ugly if/else if/else
with a dictionary:
private static IDictionary<string, string> FileDataTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
["Import"] = "Source Data",
// ..
The also not so pretty Contains
can be replaced with a nice regex that will grow or shirnk automatically if you add/remove mappings:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileContentsMatch = Regex.Match(fileName, $"__(?<Type>", FileDataTypes.Keys))__", RegexOptions.ExplicitCapture
Notice that both the dictionary and the regex are case insensitive. You should always make paths case insensitive in Windows. You are lucky that this worked for so long.
(Dislaimer: It's just an example so I was to lazy to implement all the empty/null checks)
I find the cleanest way is to replace the ugly if/else if/else
with a dictionary:
private static IDictionary<string, string> FileDataTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
["Import"] = "Source Data",
// ..
The also not so pretty Contains
can be replaced with a nice regex that will grow or shirnk automatically if you add/remove mappings:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileContentsMatch = Regex.Match(fileName, $"__(?<Type>", FileDataTypes.Keys))__", RegexOptions.ExplicitCapture
Notice that both the dictionary and the regex are case insensitive. You should always make paths case insensitive in Windows. You are lucky that this worked for so long.
(Dislaimer: It's just an example so I was to lazy to implement all the empty/null checks)
edited Aug 2 at 7:51
answered Aug 2 at 7:38
t3chb0t
31.8k54095
31.8k54095
add a comment |Â
add a comment |Â
up vote
2
down vote
You're searching through the file name for each type until you find one. If you use the __
as delimiters and find the indexes of the string between them, you will only search the whole string once.
By extracting the substring with the type, now you can use a switch
block to return the appropriate value:
private static string GetFileDataType(string fullFileNameWithPath)
const string Delimiter = "__";
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
int indexA = fileName.IndexOf(Delimiter);
string type = "";
if(indexA != -1 && indexA != 0)
indexA += 2;
int indexB = fileName.IndexOf(Delimiter, indexA);
if(indexB != -1)
type = fileName.Substring(indexA, indexB - indexA);
switch(type)
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
default:
return "General";
If the string is empty or malformed "General" will be returned. Because the check for this is in one place it can easily be changed, if desired.
You can just use.Trim('_')
to remove the leading and trailing underscores ;-)
â t3chb0t
Aug 1 at 18:53
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named groupType
.
â t3chb0t
Aug 1 at 19:57
2
This doesn't produce the same result like the original code. For__Transform__SomeMoreText
it returns "General", fornull
it throws an exception, forstring.Empty
it returns "General" instead ofstring.empty
, for__Some__Export__SomeMoreText
it returns "General" instead ofDestination Data
â Heslacher
Aug 2 at 5:45
 |Â
show 3 more comments
up vote
2
down vote
You're searching through the file name for each type until you find one. If you use the __
as delimiters and find the indexes of the string between them, you will only search the whole string once.
By extracting the substring with the type, now you can use a switch
block to return the appropriate value:
private static string GetFileDataType(string fullFileNameWithPath)
const string Delimiter = "__";
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
int indexA = fileName.IndexOf(Delimiter);
string type = "";
if(indexA != -1 && indexA != 0)
indexA += 2;
int indexB = fileName.IndexOf(Delimiter, indexA);
if(indexB != -1)
type = fileName.Substring(indexA, indexB - indexA);
switch(type)
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
default:
return "General";
If the string is empty or malformed "General" will be returned. Because the check for this is in one place it can easily be changed, if desired.
You can just use.Trim('_')
to remove the leading and trailing underscores ;-)
â t3chb0t
Aug 1 at 18:53
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named groupType
.
â t3chb0t
Aug 1 at 19:57
2
This doesn't produce the same result like the original code. For__Transform__SomeMoreText
it returns "General", fornull
it throws an exception, forstring.Empty
it returns "General" instead ofstring.empty
, for__Some__Export__SomeMoreText
it returns "General" instead ofDestination Data
â Heslacher
Aug 2 at 5:45
 |Â
show 3 more comments
up vote
2
down vote
up vote
2
down vote
You're searching through the file name for each type until you find one. If you use the __
as delimiters and find the indexes of the string between them, you will only search the whole string once.
By extracting the substring with the type, now you can use a switch
block to return the appropriate value:
private static string GetFileDataType(string fullFileNameWithPath)
const string Delimiter = "__";
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
int indexA = fileName.IndexOf(Delimiter);
string type = "";
if(indexA != -1 && indexA != 0)
indexA += 2;
int indexB = fileName.IndexOf(Delimiter, indexA);
if(indexB != -1)
type = fileName.Substring(indexA, indexB - indexA);
switch(type)
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
default:
return "General";
If the string is empty or malformed "General" will be returned. Because the check for this is in one place it can easily be changed, if desired.
You're searching through the file name for each type until you find one. If you use the __
as delimiters and find the indexes of the string between them, you will only search the whole string once.
By extracting the substring with the type, now you can use a switch
block to return the appropriate value:
private static string GetFileDataType(string fullFileNameWithPath)
const string Delimiter = "__";
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
var fileDataType = string.Empty;
int indexA = fileName.IndexOf(Delimiter);
string type = "";
if(indexA != -1 && indexA != 0)
indexA += 2;
int indexB = fileName.IndexOf(Delimiter, indexA);
if(indexB != -1)
type = fileName.Substring(indexA, indexB - indexA);
switch(type)
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
default:
return "General";
If the string is empty or malformed "General" will be returned. Because the check for this is in one place it can easily be changed, if desired.
answered Aug 1 at 18:35
tinstaafl
5,482625
5,482625
You can just use.Trim('_')
to remove the leading and trailing underscores ;-)
â t3chb0t
Aug 1 at 18:53
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named groupType
.
â t3chb0t
Aug 1 at 19:57
2
This doesn't produce the same result like the original code. For__Transform__SomeMoreText
it returns "General", fornull
it throws an exception, forstring.Empty
it returns "General" instead ofstring.empty
, for__Some__Export__SomeMoreText
it returns "General" instead ofDestination Data
â Heslacher
Aug 2 at 5:45
 |Â
show 3 more comments
You can just use.Trim('_')
to remove the leading and trailing underscores ;-)
â t3chb0t
Aug 1 at 18:53
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named groupType
.
â t3chb0t
Aug 1 at 19:57
2
This doesn't produce the same result like the original code. For__Transform__SomeMoreText
it returns "General", fornull
it throws an exception, forstring.Empty
it returns "General" instead ofstring.empty
, for__Some__Export__SomeMoreText
it returns "General" instead ofDestination Data
â Heslacher
Aug 2 at 5:45
You can just use
.Trim('_')
to remove the leading and trailing underscores ;-)â t3chb0t
Aug 1 at 18:53
You can just use
.Trim('_')
to remove the leading and trailing underscores ;-)â t3chb0t
Aug 1 at 18:53
2
2
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
Oh, or not... I now see it can by anywhere... well, then let's regex it.
â t3chb0t
Aug 1 at 19:01
1
1
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
That would probably work. But typically filenames aren't very long and unless they're processing millions of filenames, I'm not sure if there would be any appreciable performance gain.
â tinstaafl
Aug 1 at 19:04
1
1
@Shiva exactly, it's the pattern that matches the names and stores the match in the named group
Type
.â t3chb0t
Aug 1 at 19:57
@Shiva exactly, it's the pattern that matches the names and stores the match in the named group
Type
.â t3chb0t
Aug 1 at 19:57
2
2
This doesn't produce the same result like the original code. For
__Transform__SomeMoreText
it returns "General", for null
it throws an exception, for string.Empty
it returns "General" instead of string.empty
, for __Some__Export__SomeMoreText
it returns "General" instead of Destination Data
â Heslacher
Aug 2 at 5:45
This doesn't produce the same result like the original code. For
__Transform__SomeMoreText
it returns "General", for null
it throws an exception, for string.Empty
it returns "General" instead of string.empty
, for __Some__Export__SomeMoreText
it returns "General" instead of Destination Data
â Heslacher
Aug 2 at 5:45
 |Â
show 3 more comments
up vote
2
down vote
The method you have provided looks clean, is short and is easy to understand. It does what it should do but calls Contains()
in the worst case 3 times which could be avoided.
A filedatatype other than General
can only happen if at least the delimiter __
is found twice. So why don't we Split()
the filname and if we get an array which length is at least 3
we have something to work with.
Let us assume the filename without extension reads SomeFile__Export__SomeMoreText
if we call Split()
using __
as splitting argument we would get "SomeFile", "Export", "SomeMoreText"
now we can easily iterate over the array starting at the second element and ending at the element before last and using a switch
on each element to gain the desired filedatatype.
Overall this would look like
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;
var possibleFileDataTypes = fileName.Split(new string "__" , StringSplitOptions.None);
if (possibleFileDataTypes.Length < 3) return "General";
for (var i = 1; i < possibleFileDataTypes.Length - 1; i++)
switch (possibleFileDataTypes[i])
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
return "General";
and produces the following results
GetFileDataType(string.Empty) -> string.Emtpty
GetFileDataType(null) -> string.Emtpty
GetFileDataType(@"C:folderText__Export__SomeOtherText.txt") -> "Destination Data"
GetFileDataType(@"C:folderText__SomeOtherText__SomeMoreText.txt") -> "General"
GetFileDataType(@"C:folderSome__File__Import__Some__More__Text.txt") -> "Source Data"
GetFileDataType(@"C:folder__Transform__Some__More__Text.txt") -> "Transformational Data"
GetFileDataType(@"C:folder__Export__.txt") -> "Destination Data"
GetFileDataType(@"C:folder__Export.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
add a comment |Â
up vote
2
down vote
The method you have provided looks clean, is short and is easy to understand. It does what it should do but calls Contains()
in the worst case 3 times which could be avoided.
A filedatatype other than General
can only happen if at least the delimiter __
is found twice. So why don't we Split()
the filname and if we get an array which length is at least 3
we have something to work with.
Let us assume the filename without extension reads SomeFile__Export__SomeMoreText
if we call Split()
using __
as splitting argument we would get "SomeFile", "Export", "SomeMoreText"
now we can easily iterate over the array starting at the second element and ending at the element before last and using a switch
on each element to gain the desired filedatatype.
Overall this would look like
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;
var possibleFileDataTypes = fileName.Split(new string "__" , StringSplitOptions.None);
if (possibleFileDataTypes.Length < 3) return "General";
for (var i = 1; i < possibleFileDataTypes.Length - 1; i++)
switch (possibleFileDataTypes[i])
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
return "General";
and produces the following results
GetFileDataType(string.Empty) -> string.Emtpty
GetFileDataType(null) -> string.Emtpty
GetFileDataType(@"C:folderText__Export__SomeOtherText.txt") -> "Destination Data"
GetFileDataType(@"C:folderText__SomeOtherText__SomeMoreText.txt") -> "General"
GetFileDataType(@"C:folderSome__File__Import__Some__More__Text.txt") -> "Source Data"
GetFileDataType(@"C:folder__Transform__Some__More__Text.txt") -> "Transformational Data"
GetFileDataType(@"C:folder__Export__.txt") -> "Destination Data"
GetFileDataType(@"C:folder__Export.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
add a comment |Â
up vote
2
down vote
up vote
2
down vote
The method you have provided looks clean, is short and is easy to understand. It does what it should do but calls Contains()
in the worst case 3 times which could be avoided.
A filedatatype other than General
can only happen if at least the delimiter __
is found twice. So why don't we Split()
the filname and if we get an array which length is at least 3
we have something to work with.
Let us assume the filename without extension reads SomeFile__Export__SomeMoreText
if we call Split()
using __
as splitting argument we would get "SomeFile", "Export", "SomeMoreText"
now we can easily iterate over the array starting at the second element and ending at the element before last and using a switch
on each element to gain the desired filedatatype.
Overall this would look like
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;
var possibleFileDataTypes = fileName.Split(new string "__" , StringSplitOptions.None);
if (possibleFileDataTypes.Length < 3) return "General";
for (var i = 1; i < possibleFileDataTypes.Length - 1; i++)
switch (possibleFileDataTypes[i])
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
return "General";
and produces the following results
GetFileDataType(string.Empty) -> string.Emtpty
GetFileDataType(null) -> string.Emtpty
GetFileDataType(@"C:folderText__Export__SomeOtherText.txt") -> "Destination Data"
GetFileDataType(@"C:folderText__SomeOtherText__SomeMoreText.txt") -> "General"
GetFileDataType(@"C:folderSome__File__Import__Some__More__Text.txt") -> "Source Data"
GetFileDataType(@"C:folder__Transform__Some__More__Text.txt") -> "Transformational Data"
GetFileDataType(@"C:folder__Export__.txt") -> "Destination Data"
GetFileDataType(@"C:folder__Export.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
The method you have provided looks clean, is short and is easy to understand. It does what it should do but calls Contains()
in the worst case 3 times which could be avoided.
A filedatatype other than General
can only happen if at least the delimiter __
is found twice. So why don't we Split()
the filname and if we get an array which length is at least 3
we have something to work with.
Let us assume the filename without extension reads SomeFile__Export__SomeMoreText
if we call Split()
using __
as splitting argument we would get "SomeFile", "Export", "SomeMoreText"
now we can easily iterate over the array starting at the second element and ending at the element before last and using a switch
on each element to gain the desired filedatatype.
Overall this would look like
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;
var possibleFileDataTypes = fileName.Split(new string "__" , StringSplitOptions.None);
if (possibleFileDataTypes.Length < 3) return "General";
for (var i = 1; i < possibleFileDataTypes.Length - 1; i++)
switch (possibleFileDataTypes[i])
case "Import":
return "Source Data";
case "Export":
return "Destination Data";
case "Transform":
return "Transformational Data";
return "General";
and produces the following results
GetFileDataType(string.Empty) -> string.Emtpty
GetFileDataType(null) -> string.Emtpty
GetFileDataType(@"C:folderText__Export__SomeOtherText.txt") -> "Destination Data"
GetFileDataType(@"C:folderText__SomeOtherText__SomeMoreText.txt") -> "General"
GetFileDataType(@"C:folderSome__File__Import__Some__More__Text.txt") -> "Source Data"
GetFileDataType(@"C:folder__Transform__Some__More__Text.txt") -> "Transformational Data"
GetFileDataType(@"C:folder__Export__.txt") -> "Destination Data"
GetFileDataType(@"C:folder__Export.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
GetFileDataType(@"C:folder____.txt") -> "General"
answered Aug 2 at 5:35
Heslacher
43.8k359152
43.8k359152
add a comment |Â
add a comment |Â
up vote
0
down vote
A different approach based on the idea to use something like a dictonary (t3chb0t's answer) is using two arrays of strings internally. One to check if this "string-component" is present in the file name, the other one to return the file type.
Using these two you need to iterate the first array and return from the second array using same index if you find something.
This removes the if/else structure and seems to be easy to read to me, eventough (or maybe because) it is not as advanced as the other answers and keeps the contains().
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName))
return string.Empty;
String fileNameComponents = "__Import__", "__Export__", "__Transform__" ;
String fileTypes = "Source Data", "Destination Data", "Transformational Data" ;
for (int i = 0; i < fileNameComponents.Length; i++)
if (fileName.Contains(fileNameComponents[i]))
return fileTypes[i];
return "General";
This approach only aims at the core of the question (removing the if/else) whitout considering any improvments to performance.
add a comment |Â
up vote
0
down vote
A different approach based on the idea to use something like a dictonary (t3chb0t's answer) is using two arrays of strings internally. One to check if this "string-component" is present in the file name, the other one to return the file type.
Using these two you need to iterate the first array and return from the second array using same index if you find something.
This removes the if/else structure and seems to be easy to read to me, eventough (or maybe because) it is not as advanced as the other answers and keeps the contains().
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName))
return string.Empty;
String fileNameComponents = "__Import__", "__Export__", "__Transform__" ;
String fileTypes = "Source Data", "Destination Data", "Transformational Data" ;
for (int i = 0; i < fileNameComponents.Length; i++)
if (fileName.Contains(fileNameComponents[i]))
return fileTypes[i];
return "General";
This approach only aims at the core of the question (removing the if/else) whitout considering any improvments to performance.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
A different approach based on the idea to use something like a dictonary (t3chb0t's answer) is using two arrays of strings internally. One to check if this "string-component" is present in the file name, the other one to return the file type.
Using these two you need to iterate the first array and return from the second array using same index if you find something.
This removes the if/else structure and seems to be easy to read to me, eventough (or maybe because) it is not as advanced as the other answers and keeps the contains().
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName))
return string.Empty;
String fileNameComponents = "__Import__", "__Export__", "__Transform__" ;
String fileTypes = "Source Data", "Destination Data", "Transformational Data" ;
for (int i = 0; i < fileNameComponents.Length; i++)
if (fileName.Contains(fileNameComponents[i]))
return fileTypes[i];
return "General";
This approach only aims at the core of the question (removing the if/else) whitout considering any improvments to performance.
A different approach based on the idea to use something like a dictonary (t3chb0t's answer) is using two arrays of strings internally. One to check if this "string-component" is present in the file name, the other one to return the file type.
Using these two you need to iterate the first array and return from the second array using same index if you find something.
This removes the if/else structure and seems to be easy to read to me, eventough (or maybe because) it is not as advanced as the other answers and keeps the contains().
private static string GetFileDataType(string fullFileNameWithPath)
// extract filename only
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
if (string.IsNullOrWhiteSpace(fileName))
return string.Empty;
String fileNameComponents = "__Import__", "__Export__", "__Transform__" ;
String fileTypes = "Source Data", "Destination Data", "Transformational Data" ;
for (int i = 0; i < fileNameComponents.Length; i++)
if (fileName.Contains(fileNameComponents[i]))
return fileTypes[i];
return "General";
This approach only aims at the core of the question (removing the if/else) whitout considering any improvments to performance.
edited 9 hours ago
answered 9 hours ago
Andre P
412
412
add a comment |Â
add a comment |Â
up vote
0
down vote
Composing with a list of functions, one can drastically reduce the number of needed lines:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
return matchingRules.First(tuple => tuple.Item1(fileName)).Item2;
With matchingRules
declared as follow:
var matchingRules = new List<(Func<string, bool>, string)>();
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Import__"), "Source Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Export__"), "Destination Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Transform__"), "Transformational Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f), "General"));
matchingRules.Add((f => true, string.Empty));
add a comment |Â
up vote
0
down vote
Composing with a list of functions, one can drastically reduce the number of needed lines:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
return matchingRules.First(tuple => tuple.Item1(fileName)).Item2;
With matchingRules
declared as follow:
var matchingRules = new List<(Func<string, bool>, string)>();
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Import__"), "Source Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Export__"), "Destination Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Transform__"), "Transformational Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f), "General"));
matchingRules.Add((f => true, string.Empty));
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Composing with a list of functions, one can drastically reduce the number of needed lines:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
return matchingRules.First(tuple => tuple.Item1(fileName)).Item2;
With matchingRules
declared as follow:
var matchingRules = new List<(Func<string, bool>, string)>();
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Import__"), "Source Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Export__"), "Destination Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Transform__"), "Transformational Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f), "General"));
matchingRules.Add((f => true, string.Empty));
Composing with a list of functions, one can drastically reduce the number of needed lines:
private static string GetFileDataType(string fullFileNameWithPath)
var fileName = Path.GetFileNameWithoutExtension(fullFileNameWithPath);
return matchingRules.First(tuple => tuple.Item1(fileName)).Item2;
With matchingRules
declared as follow:
var matchingRules = new List<(Func<string, bool>, string)>();
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Import__"), "Source Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Export__"), "Destination Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f) && f.Contains("__Transform__"), "Transformational Data"));
matchingRules.Add((f => !string.IsNullOrWhiteSpace(f), "General"));
matchingRules.Add((f => true, string.Empty));
answered 9 hours ago
Spotted
54928
54928
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200766%2fuse-filename-to-determine-file-type%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
You need to explain what your code is doing first.
â t3chb0t
Aug 1 at 17:24
Apologies, thought it was "self describing"... my bad. I've added the explanation to my question.
â Shiva
Aug 1 at 17:38
2
I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
â Sam Onela
Aug 1 at 17:43
@SamOnela I looked at the site goals link you provided and you are right. The title looks appropriate :)
â Shiva
Aug 1 at 17:57