Lets say i have
int a = 1;
int b = 2;
string exp = "b > a";
and i want to evaluate the string expression with those variables
if(exp.SomeKindOfParseOrCast())
{
//here be magic
}
Is it possible in any simple way?
Nope, not in C# - these are parameter names, and thus are compile time values, and this expression parsing you are describing is done in runtime - the computer doesn't know the name of the parameters while it's being evaluated. Instead, you could do something a little more strict, like an expression parser - implement your own way to parse string expressions.
Very very simplified:
if(exp.Equals("b > a"))
{
if(b>a)
// do what you do if b is bigger than a
else
// do what you do with a wrong expression
}
else if (exp.Equals("a > b")
{
if(a>b)
// do what you do if a is bigger than b
else
// do what you do with a wrong expression
}
else if (exp.Equals("a = b")
{
if(a==b)
// do what you do if a is equal to b
else
// do what you do with a wrong expression
}
else
// do what you do with a badly formatted expression
if you would like to take this a step forward, you can cut spaces, make sure the expression is lowercase, etc. - there's many examples around, I personally like this one.
Is it possible in any simple way?
No, in C# this is not possible in a simple way like it were in languages such as JavaScript with its eval function. Anyway, you'd have to provide bindings of in-expression parameters to actual values.
You can use Roslyn.
Here is an example of how to compile and run your own code in runtime.
Disclaimer: I'm the owner of the project Eval Expression.NET
This library is very easy to use and allow to evaluate and compile almost all the C# language.
// For single evaluation
var value1 = Eval.Execute<bool>("b > a", new { a = 1, b = 2 });
// For many evaluation
var compiled = Eval.Compile<Func<int, int, bool>>("b > a", "a", "b");
var value2 = compiled(1, 2);
Related
In the below code, I am repeating the same code twice except one change. If there is a way to write the same in single line then it would be great.
The only changes I made is Obsc and zp based on the if..else statement.
var zp = __Services.GetValue("Z", Order.Code);
var St="";
if(sp.Label != null)
{
var Obsc = _Services.GetValue("Z", sp.Label);
St= string.Format(Obsc, .......,userProfile.DisplayName());
}
else
{
St = string.Format(zp, ......., userProfile.DisplayName());
}
Are you happy with something like this?
var code = sp.Label is null
? Order.Code
: sp.Label;
var zpOrObsc = service.GetValue("Z", code); // please use a valid variable name
var st = string.Format(zpOrObsc, ......, userProfile.DisplayName());
St = string.Format(_Services.GetValue("Z", sp.Label ?? Order.Code), ......., userProfile.DisplayName());
Make a variable to determine which parameter value you want to call GetValue with. You only need to call GetValue once and string.Format once.
var whateverTheSecondParamForGetValueIs = Order.Code;
if (sp.Label != null) {
whateverTheSecondParamForGetValueIs = sp.Label;
}
var zp = _Services.GetValue("Z", Order.Code);
var St = string.Format(zp, ......., userProfile.DisplayName());
No, this isn't a "single line", but I don't see the appeal in that. To me, this is much more readable than any ternary operator.
I'm also going to say that these variable names need quite an improvement. They don't convey any meaning.
The ternary (*) operator, also known as the "conditional operator" is basically a short-hand for "if then else " and is written like so:
result = condition ? trueValue : falseValue;
It is not comparable to an actual if ... else ... statement as it is an expression and must provide a value.
See its documentation in the C# language reference for full details: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator.
*) So called because it is the only operator that takes 3 arguments. Compare with "binary operator" and "unary operator".
In Visual Basic, there is this IIF Function, as in Crystal Report, etc ...
In C # itself, this function does not exist, but it is the same as doing something like this:
bool a = true;
string b = a ? "is_True" : "is_False";
But for the code to be a bit easier to read I wanted to do it as a function for C #, leaving it like this:
public static T IIf<T>(bool expression, T truePart, T falsePart)
{
return expression ? truePart : falsePart;
}
Or to not operate with the real values can also be done using delegates, to access the necessary values:
public static T IIf<T>(bool expression, Func<T> truePart, Func<T> falsePart)
{
return expression ? truePart() : falsePart();
}
So far this works well ...
But how can I modify this function so I can take 2N + 1 arguments?
(N - the number of logical expressions specified)
Example the desired result:
Each odd argument specifies a logical expression;
Each even argument specifies the value that is returned if the previous expression evaluates to true;
The last argument specifies the value that is returned if the previously evaluated logical expressions yielded false.
int value = IIf(Name = "Joel", 1, Name = "Peter", 2, Name = "Maria", 3, 4);
Can someone give me a hand with this?
Environment: C # - Visual Studio 2017
First off, as noted in the comments, this is a bad idea. Newer versions of C# already support pattern-matching switches as a built-in feature of the language; use it.
Second, this is a bad idea because the API of "argument, case1, result1, case2, result2, ..." has a signature that is hard to express in the C# type system.
Were I forced to implement such an API, I would suggest using tuples:
public static R Switch<A, R>(
A item,
R theDefault,
params (A, R)[] cases )
{
foreach(var c in cases)
if (item.Equals(c.Item1))
return c.Item2;
return theDefault;
}
Or, make a helpful utility method and use it:
public static T FirstOrDefault(
this IEnumerable<T> items,
T theDefault,
Func<T, bool> predicate)
{
foreach(var i in items.Where(predicate))
return i;
return theDefault;
}
public static R Switch<A, R>(
A item,
R theDefault,
params (A, R)[] cases ) =>
cases.FirstOrDefault(
(item, theDefault),
c => item.Equals(c.Item1)).Item2;
If you cannot use tuples because you're using an older version of C#, you could make your own pair type or use the key-value pair type.
But just do not go there. If you need a switch, write a switch. If you need a dictionary, write a dictionary.
If you want to preserve the order of your parameters, which presumably you do if you're trying so hard to make the function replicate what you've seen elsewhere, then you can write something like this:
public T IIf<T>(params object[] objects) {
for(var i = 0; i < objects.Length - 1; i += 2)
if((bool)objects[i])
return (T)objects[i+1];
return (T)objects[objects.Length - 1];
}
But it's a good lesson in why you would avoid something like this. Firstly, you have to explicitly declare the type you're working with. So you'd have to use it like this:
var value = IIf<int>(Name == "Joel", 1, Name == "Peter", 2, Name == "Maria", 3, 4);
Notice the passing of 'int' as a type parameter. You can avoid that by changing the order of the parameters so that the default comes first.
But, if you're just willing to adopt a personal pattern, the nested ternary syntax can be quite readable:
var value =
Name == "Joel" ? 1
: Name == "Peter" ? 2
: Name == "Maria" ? 3
: 4;
If you don't feel it's readable, then it's just because it takes some getting used to. Imagine going the other way, from a C# developer to VB, and seeing 'IIF'. You'd be thinking, "why do they add the extra 'I' in 'IF'?". I should make a function "IF" that emulates "IIF". But that would be a bad idea, wouldn't it?
is it possible to evaluate a single string in c#. The string itself will only be determined during run-time and therefore cannot be set before hand. please see example:
var a = "a == b";
if(a){
//do something
}
EDITED:
This is a actual example of what i would like computed:
var evaluationToBeDone = "MUST_CE_I = \"MUST_CE_I\"";
if(evaluationToBeDone){
// i will do something if the above is true
}
I see what you're trying to do, but the approach doesn't make sense. When you make a variable into an object, the program only reads it as letters, not any logic inside of the object. Try doing this:
var a = "MUST_CE_I"
var b = "\"MUST_CE_I\""
if (a == b)
{
do stuff
}
I assume you want your second string to have the " " quotes, so this should give you what you need. Even though the if statement will always return false since the two variables are not equal.
I'm relatively new to programming, and I'm currently working on a C# string based calculator. A lot of it works fine already, but I'm having problems with negative coefficients. My calculator engine always looks for the next operator and calculates accordingly, so the problem is that if I want to calculate "-5+6", the first operation is "-5", but it obviously can't be calculated. How can I separate operator and coefficient?
What I've come up with so far (small extract of the whole code)
if (nextOperation.Contains("+"))
{
string firstOperationResult = Calculate(nextOperation.Split('+').ToList(), "+")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, firstOperationResult);
return CalculateDashOperation(partialFormulaReplacement);
}
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") > 0)
{
string resultOfFirstOperation = Calculate(nextOperation.Split('-').ToList(), "-")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, resultOfFirstOperation);
return CalculateDashOperation(partialFormulaReplacement);
}
//added
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") == 0)
{
//what to do
}
//added
return partialFormula;
"-5" can be treated as meaning "0-5", so you could say there's an implicit zero if you see an operand in the first position of the string. Note that this approach will only work for the operators + and -.
As for the problem of attempting to calculate "-5" again, I suggest you use the 0 as an argument to your Calculate function, rather than prepending it to the string you're processing:
Calculate(new List<string>{"0", nextOperation[1]}, "-")
Also, as has been pointed out in the comments, this approach will not cover all possible cases, and if this isn't an academic exercise then there are solutions out there that already solve this problem.
The sample code looks a little short. But let's try to suggest:
nextOperation is a string containing something like "1 * -6 + 6"
In order to evaluate this expression yout have to 'encrypt' your string first.
The topic you are looking for is parenthesis
A nice explanation of the basic (in python) can be found here.
But this question is already answered here.
Use NCalc Library:
Dont reinvent wheel, * and / priorities is already implemented.
Simple expressions
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
Handles mathematical functional from System.Math
Debug.Assert(0 == new Expression("Sin(0)").Evaluate());
Debug.Assert(2 == new Expression("Sqrt(4)").Evaluate());
Debug.Assert(0 == new Expression("Tan(0)").Evaluate());
This question already has answers here:
Is there a string math evaluator in .NET?
(18 answers)
Closed 9 years ago.
I have a string of the following type:
"23 + 323 =" or "243 - 3 ="
So the format is: number + operator + number = equal.
And I also have an int which is the answer to that question.
How can I parse the string and check if the answer is correct?
Thank You,
Miguel
Maybe using regular expressions you can do something like...
String sExpression = "23 + 323 =";
int nResult = 0;
Match oMatch = Regex.Match(#"(\d+)\s*([+-*/])\s*(\d+)(\s*=)?")
if(oMatch.Success)
{
int a = Convert.ToInt32(oMatch.Groups[1].Value);
int b = Convert.ToInt32(oMatch.Groups[3].Value);
switch(oMatch.Groups[2].Value)
{
case '+';
nResult = a + b;
break;
case '-';
nResult = a - b;
break;
case '*';
nResult = a * b;
break;
case '/';
nResult = a / b;
break;
}
}
and extend to your need.. (floats, other operators, validations, etc)
You want to split on equals then split on the operator. Then you can use some standard string processing techniques to do the operation and check it against the answer. There are probably far more efficient and/or cleaner solutions than this, this is simply the first one at my fingertips and since you didn't post any code it is what you get. Note that this also is not flexible. It only works when there are two operands and with the four primary arithmetic operators. Unless there's some requirement saying you don't use third party libraries I'd recommend using something like what's linked to in the comments. If you need to implement this in a more general sense (works with multiple operations like (x + y - z) * x ) then you have a lot more work cut out for you.
string input = "23 + 323 = 346";
string[] sides = input.Split('=');
string[] operands;
int answer = 0;
if (sides.Length == 2)
{
if (sides[0].Contains('+'))
{
operands = sides[0].Split('+');
operands[0].Trim();
operands[1].Trim();
answer = int.Parse(operands[0]) + int.Parse(operands[1]);
// note if you're serious about error handling use tryparse to ensure the values are integers
if (answer != int.Parse(sides[1].Trim()))
// answer is wrong
}
else if (sides[0].Contains('-'))
{
// same logic
}
}
else
//input formatting error
As all of the comments to your question indicate, you need some kind of tokenizer, expression parser, and expression evaluator.
The tokenizer splits the source string into separate tokens, like numbers and operators.
The expression parser scans and syntactically parses the sequence of tokens, recognizing expressions and building some kind of parse tree (i.e., an abstract expression tree).
The expression evaluator then walks the nodes of the resulting expression tree, evaluating the binary and unary subexpressions. The result is the evaluation of the top-most node in the tree.
This is all quite a complex set of things to do, so (like the other comments state), you should try to find a library that someone has already written to do all this for you.
Actually it is not that different from parsing single arithmetic expression. Here you simply evaluate two of them (on both sides of equal sign) and then check the outcome.
Well, you can go "crazy", and parse not only = but >, >= too, which will give you more flexibility.
Because in arithmetic expression parenthesis should be legal (common sense), for example (5+2)*3 you should avoid struggle with regexes and alike approaches and go with parser.
Pick one you feel comfortable with, GOLD, ANTLR, Cocoa. My own parser (generator) -- NLT -- contains already arithmetic expression example. Add single rule for checking equality and you are ready to go.