Simplifying many possibilities in c# indexof condition [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Is there any way to simplify this code? The input is a string.
private string IfItIsPicture(string URI_obrazku)
{
if (URI_obrazku.IndexOf(".jpg") > -1 ||
URI_obrazku.IndexOf(".png") > -1 ||
URI_obrazku.IndexOf(".bmp") > -1 ||
URI_obrazku.IndexOf(".tiff") > -1 ||
URI_obrazku.IndexOf(".tif") > -1 ||
URI_obrazku.IndexOf(".jpeg") > -1 ||
URI_obrazku.IndexOf(".jpg") > -1 ||
URI_obrazku.IndexOf(".svg") > -1 ||
URI_obrazku.IndexOf(".gif") > -1)
{ ... some code }
return someString;
}
Thanks.

Use Path.GetExtension to get just the extension. Then check whether that extension is in your collection of known extensions.
private string IfItIsPicture(string URI_obrazku)
{
var knownExtensions = new [] { ".jpg",".png",".bmp", "..."};
var extension = Path.GetExtension(URI_obrazku);
if (knownExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
// ... some code
}
return "someString";
}

Use Linq:
var types = new List<string> { ".jpg", ".png", ... };
if (types.Any(t => URI_obrazku.IndexOf(t) >= 0))
{
return someString;
}

Yes, use an array
var values = new [] { ".jpg",".png",".bmp", ...};
if(values.Any(x => URI_obrazku.EndsWith(x)))

I don't know if this is better, but I bet it's faster since it isn't doing multiple IndexOfs:
private bool IsPicture(string URI_obrazku)
{
String Extension = Path.GetExtension(URI_obrazku);
switch (Extension)
{
case ".jpg": return true;
case ".png": return true;
// other extensions
default: return false;
}
}

Related

Using logical operators in shooting robot program [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
Here is the c# code that controls an artillery shooting robot.
static bool ShouldFire(bool enemyInFront, string enemyName, int robotHealth)
{
bool shouldFire = true;
if (enemyInFront == true)
{
if (enemyName == "boss")
{
if (robotHealth < 50) shouldFire = false;
if (robotHealth > 100) shouldFire = true;
}
}
else
{
return false;
}
return shouldFire;
}
The code looks awkward somewhat and could be re-written significantly shorter. Can the community at stackoverflow suggest a c# method, that would do the same as in the code above, but using one operation? I kindly ask you to make your proposals. Here is some template of what one is looking for:
static bool ShouldFire2(bool enemyInFront, string enemyName, int robotHealth)
{
return enemyInFront && (...);
}
I would appreciate some explanation, on how to achieve the desired outcome.
My suggestion is this:
static bool ShouldFire2(bool enemyInFront, string enemyName, int robotHealth)
{
return enemyInFront && (enemyName == "boss" ? robotHealth >= 50 : true);
}
You first check in there is an enemy ahead. if yes, check if it is boss and if its hp greater than 50 then return true, otherwise false. If not a boss, always return true. And false if nothing in front of your character.
The line 'if (robotHealth > 100) shouldFire = true;' does nothing. shouldFire is already true unless health is under 50.
So you can reduce that section to:
static bool ShouldFire(bool enemyInFront, string enemyName, int robotHealth)
{
bool shouldFire = true;
if (enemyInFront == true)
{
return !(enemyName != "boss" && robotHealth < 50); }
else
{
return false;
}
return shouldFire;
}
Which could be reduced to:
static bool ShouldFire(bool enemyInFront, string enemyName, int robotHealth)
{
return enemyInFront && (enemyName != "boss" || robotHealth >= 50);
}

Can a return statement returning the result of a ternary expression be made to not return for one branch of the ternary?

Is it possible to write this if statement in ternary operator (shorthand of c# if)? If yes what would it be?
if (condition)
{
return true;
}
else
{
int a = 2;
}
Thanx everyone in advance. Thank you very much.
Sorry guys if I confused you. I am trying to use ternary operator in this if else block of the method.
public static bool CompareDictionary(this Dictionary<Position, char>
dictionary1,
Dictionary<Position, char> dictionary2, out List<string> wordList)
{
string str = "";
wordList = new List<string>();
foreach (var dic1KeyVal in dictionary1)
{
Position d1key = dic1KeyVal.Key;
char d1Pos = dic1KeyVal.Value;
bool isFound = false;
foreach (var dic2KeyVal in dictionary2)
{
Position d2key = dic2KeyVal.Key;
char d2Pos = dic2KeyVal.Value;
if (d1Pos.Equals(d2Pos) && d1key == d2key)
{
isFound = true;
str = str + d1Pos.ToString();
}
}
if (isFound == false)
{
return false;
}
else
{
wordList.Add(str);
str = "";
}
}
return true;
}
Short Answer
No.
Long Answer
First of all this code does not even need an else:
if (condition)
{
return true;
}
else
{
int a = 2;
}
and can be written as:
if (condition)
{
return true;
}
int a = 2;
Now for ternary operator: Both conditions in a ternary operator must return the same thing. You cannot return a bool in one condition and then assign to a variable in another condition. If you were checking the answer to a question, for example, it would be like this:
return answer == 2 ? true : false;
Whether the answer is correct or not, we return a bool. Or it could be like this:
return answer == 2 ? 1: -1;
But not like this:
return answer == 2 ? true : "wrong"; // will not compile
No. The ternary operator just returns one out of two potential values depending on a condition.
What you can do with the ternary operator is, e.g. int a = condition ? 0 : 2 which would assign the variable a value of either 0 or 2 depending on the value of condition.
Given a more complete example of what you intend to do someone here could potentially come up with a nicer syntax.

Parse command line string into a list of strings [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I want to take the following string as input:
first-arg second-arg "third arg with spaces" "arg with \" quotes"
and return this list of strings as output
["first-arg", "second-arg", "third arg with spaces", "arg with \" quotes"]
Are there any nuget packages or built in functions that can do this? I want it to handle edge cases like arguments containing multiple words and arguments containing quotes.
string[] arguments = Environment.GetCommandLineArgs();
For more information see the MSDN website
This class satisfies the requirements. It's not the most effective way, but it returns the right arguments.
public static class ArgumentLineParser
{
public static string[] ToArguments(string cmd)
{
if (string.IsNullOrWhiteSpace(cmd))
{
return new string[0];
}
var argList = new List<string>();
var parseStack = new Stack<char>();
bool insideLiteral = false;
for (int i = 0; i < cmd.Length; i++)
{
bool isLast = i + 1 >= cmd.Length;
if (char.IsWhiteSpace(cmd[i]) && insideLiteral)
{
// Whitespace within literal is kept
parseStack.Push(cmd[i]);
}
else if (char.IsWhiteSpace(cmd[i]))
{
// Whitespace delimits arguments
MoveArgumentToList(parseStack, argList);
}
else if (!isLast && '\\'.Equals(cmd[i]) && '"'.Equals(cmd[i + 1]))
{
//Escaped double quote
parseStack.Push(cmd[i + 1]);
i++;
}
else if ('"'.Equals(cmd[i]) && !insideLiteral)
{
// Begin literal
insideLiteral = true;
}
else if ('"'.Equals(cmd[i]) && insideLiteral)
{
// End literal
insideLiteral = false;
}
else
{
parseStack.Push(cmd[i]);
}
}
MoveArgumentToList(parseStack, argList);
return argList.ToArray();
}
private static void MoveArgumentToList(Stack<char> stack, List<string> list)
{
var arg = string.Empty;
while (stack.Count > 0)
{
arg = stack.Pop() + arg;
}
if (arg != string.Empty)
{
list.Add(arg);
}
}
}
It can be used like this:
var line = #"first-arg second-arg ""third arg with spaces"" ""arg with \"" quotes""";
var args = ArgumentLineParser.ToArguments(line);

C# performance - Regex vs. multiple Split [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm working with a rather large set of strings I have to process as quickly as possible.
The format is quite fixed:
[name]/[type]:[list ([key] = [value],)]
or
[name]/[type]:[key]
I hope my representation is okay. What this means is that I have a word (in my case I call it Name), then a slash, followed by another word (I call it Type), then a colon, and it is either followed by a comma-separated list of key-value pairs (key = value), or a single key.
Name, Type cannot contain any whitespaces, however the key and value fields can.
Currently I'm using Regex to parse this data, and a split:
var regex = #"(\w+)\/(\w+):(.*)";
var r = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
var m = r.Match(Id);
if (m.Success) {
Name = m.Groups[1].Value;
Type= m.Groups[2].Value;
foreach (var intern in m.Groups[3].Value.Split(','))
{
var split = intern.Trim().Split('=');
if (split.Length == 2)
Items.Add(split[0], split[1]);
else if (split.Length == 1)
Items.Add(split[0], split[0]);
}
}
Now I know this is not the most optional case, but I'm not sure which would be the fastest:
Split the string first by the : then by / for the first element, and , for the second, then process the latter list and split again by =
Use the current mixture as it is
Use a completely regex-based
Of course I'm open to suggestions, my main goal is to achieve the fastest processing of this single string.
Its always fun to implement a custom parser. Obviously concerning code maintenance, Regex is probably the best choice, but if performance is an ultimate concern then you probably need a tailor made parser which even in the simplest syntaxes is quite a lot more of work.
I've whipped one up really quick (it might be a little hackish in some places) to see what it would take to implement one with some basic error recovery and information. This isn't tested in any way but I'd be curious, if its minimally functional, to know how well it stacks up with the Regex solution in terms of performance.
public class ParserOutput
{
public string Name { get; }
public string Type { get; }
public IEnumerable<Tuple<string, string>> KeyValuePairs { get; }
public bool ContainsKeyValuePairs { get; }
public bool HasErrors { get; }
public IEnumerable<string> ErrorDescriptions { get; }
public ParserOutput(string name, string type, IEnumerable<Tuple<string, string>> keyValuePairs, IEnumerable<string> errorDescriptions)
{
Name = name;
Type = type;
KeyValuePairs = keyValuePairs;
ContainsKeyValuePairs = keyValuePairs.FirstOrDefault()?.Item2?.Length > 0;
ErrorDescriptions = errorDescriptions;
HasErrors = errorDescriptions.Any();
}
}
public class CustomParser
{
private const char forwardSlash = '/';
private const char colon = ':';
private const char space = ' ';
private const char equals = '=';
private const char comma = ',';
StringBuilder buffer = new StringBuilder();
public ParserOutput Parse(string input)
{
var diagnosticsBag = new Queue<string>();
using (var enumerator = input.GetEnumerator())
{
var name = ParseToken(enumerator, forwardSlash, diagnosticsBag);
var type = ParseToken(enumerator, colon, diagnosticsBag);
var keyValuePairs = ParseListOrKey(enumerator, diagnosticsBag);
if (name.Length == 0)
{
diagnosticsBag.Enqueue("Input has incorrect format. Name could not be parsed.");
}
if (type.Length == 0)
{
diagnosticsBag.Enqueue("Input has incorrect format. Type could not be parsed.");
}
if (!keyValuePairs.Any() ||
input.Last() == comma /*trailing comma is error?*/)
{
diagnosticsBag.Enqueue("Input has incorrect format. Key / Value pairs could not be parsed.");
}
return new ParserOutput(name, type, keyValuePairs, diagnosticsBag);
}
}
private string ParseToken(IEnumerator<char> enumerator, char separator, Queue<string> diagnosticsBag)
{
buffer.Clear();
var allowWhitespaces = separator != forwardSlash && separator != colon;
while (enumerator.MoveNext())
{
if (enumerator.Current == space && !allowWhitespaces)
{
diagnosticsBag.Enqueue($"Input has incorrect format. {(separator == forwardSlash ? "Name" : "Type")} cannot contain whitespaces.");
}
else if (enumerator.Current != separator)
{
buffer.Append(enumerator.Current);
}
else
return buffer.ToString();
}
return buffer.ToString();
}
private IEnumerable<Tuple<string, string>> ParseListOrKey(IEnumerator<char> enumerator, Queue<string> diagnosticsBag)
{
buffer.Clear();
var isList = false;
while (true)
{
var key = ParseToken(enumerator, equals, diagnosticsBag);
var value = ParseToken(enumerator, comma, diagnosticsBag);
if (key.Length == 0)
break;
yield return new Tuple<string, string>(key, value);
if (!isList && value.Length != 0)
{
isList = true;
}
else if (isList && value.Length == 0)
{
diagnosticsBag.Enqueue($"Input has incorrect format: malformed [key / value] list.");
}
}
}
}

c# Check if all strings in list are the same [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Check if all items are the same in a List
I have a list:
{string, string, string, string}
I need to check if all the items in this list are the same then return true, if not return false.
Can i do this with LINQ?
var allAreSame = list.All(x => x == list.First());
var allAreSame = list.Distinct().Count() == 1;
or a little more optimal
var allAreSame = list.Count == 0 || list.All(x => x == list[0]);
How about this:
string[] s = { "same", "same", "same" };
if (s.Where(x => x == s[0]).Count() == s.Length)
{
return true;
}
var hasIdenticalItems = list.Count() <= 1 || list.Distinct().Count() == 1;

Categories