Click here to Skip to main content
15,887,776 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello

I'm constructing a method for which I would like to pass (amongst other things) a simple comparison expression: <left_value> <operator> <right_value>.
The method would then perform the comparison and return the result.

The data structure on either side of the expression can be a plain variable or a one-dimensional array, of type double or datetime. If the data is an array, the expression will be evaluated for each element of the array.

I was thinking of sending the expression it as a text string and then parse it, or pass the expression as three arguments (left, op and right).

Now, my problem is how to organize the code in my method. Currently I simply have one piece of code to perform the evaluation for each possible variant of the input. However, this gives me a tremendous amount of code.
2 data types * 2 types of data structures * 2 sides of the operator * minimum 6 operators gives 48 possible combinations. That's a lot of switch/select case statements to handle something which should be fairly simple.

As I will create many methods taking similar arguments, it would help a lot if I could write the code more efficiently. I am not locked to any particular way of passing the information to the method, so all options are open.

As always, all suggestions are most welcome.
Posted
Updated 15-Sep-10 6:37am
v2
Comments
DavidKiryazi 15-Sep-10 22:53pm    
So, how do you plan to compare a single variable to an array of that variable? Or even a plain variable to the datetime variable?

There are (from my calculations) 2 data types, 6 operators = 12 combinations. I don't understand where the other 36 come from? I might be missing something, but I'm sure an example of what your trying to do will help :)
Bardy85 17-Sep-10 5:19am    
Paste how you are doing it currently and I might be able to help.

your methods should be specific to a task. So if you are passing more than the expression you are doing too much in your method.

But if all your method needs is the evaluation of the expression, you can do something like this:

MyMethod(...,...,..., ProcessExpression(l,op,r),...)

Now the signature for this would be ProcessExpression( object l, string op, object r)

First thing to do is throw an exception if l.GetType() != r.GetType()

Also you need to look deep if it is an array and throw an exception if the array types are not equal.

Next you want to break up the process as two methods:
InternalProcess( object l, string op, object r) -AND-
InternalArrayProcess( IList l, string op, IList r )

Inside the latter process you just are iterating through each element in the array and calling InternalProcess(l[index], op, r[index])

You still have to do a case statement by types but you should only have to do it for the specific types you are working with on the first operand.
 
Share this answer
 
Comments
Fossie1973 21-Sep-10 9:20am    
Reason for my vote of 5
Automatic vote of 5 for accepting answer.
First, thank you for your comments, and sorry for my late reply.
In my project I am making my own custom math class, and I am currently working on methods for simple arithmetics on arrays. I need to perform math operations (+-/*) on array-to-array and array-to-variable. Also, and this is where my question fits; I would like to be able to add conditions on which the calculations will be done.

An example:
Say I have three arrays; A(10), B(10), C(10), all double.
Arrays A and B is to be added element by element, but only on elements where array C < 1 (for the same index number).

Another example:
Same as above, only B is a simple variable and not an array. B should then be added to A on all of A's elements where the corresponding value of C is less than 1.

My initial attempt was to throw all of this into one method, giving me too many alternatives on how to perform the calculations. My method took two arguments for the arrays to be added (A, B), as well as an expression for the conditions. The expression taken could be some sort of string like "if C < 1", or ideally even more complex variants; "if (C+A)/B < B+1". However, I found that parsing and executing such a string was not a simple task (to me!), so I lowered my aim and put three more arguments in my method; A left side (C), an operator string ("<") and a right side (1). As both sides could be either a variable or an array, and of datatypes double or datetime, and the operator could be of six types, I get 4 possibilities on the left side (double variable, double array, datetime variable, datetime array), 4 on the right side and 6 operator types. 4*4*6 = 96 possibilities (not 48 like I miscalculated in my initial post)

In stead of throwing all the code in one big method, I could overload it for different data types (double/datetime) and container types (variable/array), but that leaves me with exactly the same amount of code to maintain. It's just chopped up differently. And one could argue that it's actually simpler to keep it all in one massive method as then you have all the code in one place. If you need to do changes to the code at a later stage, you're sure you don't forget to update any of the overloads.

One simplification I was hoping to achieve was to pass the operator as an operator object of some sort, which could be included directly in the mathematical expression ( C(i) 'op' 1 ). This is possible in other languages like macro programming in SAS (if any of you have been in contact with that). Is it in .NET? Or does there exist some other way of achieving the same effect?

The closest to a solution I've gotten so far is to create my own data classes, and then overload the operators of the classes to perform the calculations the way I wanted them. This would actually be an excellent solution, had it not been that passing arguments to such overloads can only be done by value, not by reference. Testing showed that the performance of such a class was less than half of what could be achieved using a method taking a reference as arguments. As some of these calculations will run for hours and days, halving performance feels like a big concession to make.

Sorry if this was too verbose, just trying to explain what I'm trying to achieve.
 
Share this answer
 
Usually what I do when faced with a problem like this is to try and figure out ways of accomplishing this by working it out in a dummy class that I keep changing til I get the results.

What I don't believe you need, though, is passing values by reference. Passing by value is fine as long as you return the specific values needed.

You could try generics, for example, to see if that buys you anything. And play further with the overloads.

Have your methods become an iterative return so your IList method signature does numerous Answer<t>.Add( Compute( listA, op, listB))

Beyond that, I really don't have the time to think deeper on this problem. Try different things based on what I listed in my first answer and expand upon it until you get the best answer.

In the model I presented, making each call return a value (either the original object type or an element in an array) you never have to be concerned with how the data is being passed to you. Becoming dependant on reference values is at best risky, and possilbe dangerous. On the other hand, by returning the answer as an IList you give the caller the flexibility to a) leave the original arrays alone -or- b) assign one of the arrays to the answers returned.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900