I am checking whether the new name already exists or not.
Code 1
if(cmbxExistingGroups.Properties.Items.Cast<string>().ToList().Exists(txt => txt==txtNewGroup.Text.Trim())) {
MessageBox.Show("already exists.", "Add new group");
}
Otherwise I could have written:
Code 2
foreach(var str in cmbxExistingGroups.Properties.Items)
{
if(str==txtNewGroup.Text) {
MessageBox.Show("already exists.", "Add new group");
break;
}
}
I wrote these two and thought I was exploiting language features in code 1.
...and yes: both of them work for me ... I am wondering about the performance :-/
I appreciate the cleverness of the first sample (assuming it works), but the second one is a lot easier for the next person who has to maintain the code to figure out.
Sometimes just a little indentation makes a world of difference:
if (cmbxExistingGroups.Properties.Items
.Cast<string>().ToList()
.Exists
(
txt => txt==txtNewGroup.Text.Trim()
))
{
MessageBox.Show("already exists.", "Add new group");
}
Since your using a List<String>, you might as well just drop the Exists predicate and use Contains...use Exists when comparing complex objects by unique values.
I've quoted it before but I'll do it again:
Write your code as if the person maintaining it is a homicidal maniac
who knows where you live.
would
cmbxExistingGroups.Properties.Items.Contains(text)
not work instead?
There are a few things wrong here:
1) The two bits of code don't do the same thing - the first looks for the trimmed version of txtNewGroup, the second just looks for txtNewGroup
2) There's no point in calling ToList() - that just make things less efficient
3) Using Exists with a predicate is overkill - Contains is all you need here
So, the first could easily come down to:
if (cmbxExistingGroups.Properties.Items.Cast<string>.Contains(txtNewGroup.Text))
{
// Stuff
}
I'd probably create a variable to give "cmbxExistingGroups.Properties.Items.Cast" a meaningful, simple name - but then I'd say it's easier to understand than the explicit foreach loop.
The first code bit is fine, except instead of calling Enumerable.ToList() and List<T>.Exists(), you should just call Enumerable.Any() -- it does a lazy evaluation, so it never allocates the memory for the List<T>, and it will stop enumerating cmbxExistingGroups.Properties.Items and casting them to string. Also, calling the trim from inside that predicate means it happens for every item it looks at. It would be best to move it out to the outer scope:
string match = txtNewGroup.Text.Trim();
if(cmbxExistingGroups.Properties.Items.Cast<string>().Any(txt => txt==match)) {
MessageBox.Show("already exists.", "Add new group");
}
Verbosity in coding is not always bad at all. I prefer the second code snippet a lot over the first one. Just imagine you would have to maintain (or even change the functionality of) the first example... um.
Well, if it were me, it would be a variation on 2. Always prefer readability over one-liners. Additionally, always extract a method to make it clearer.
your calling code becomes
if( cmbxExistingGroups.ContainsKey(txtNewGroup.Text) )
{
MessageBox.Show("Already Exists");
}
If you define an extension method for Combo Boxes
public static class ComboBoxExtensions
{
public static bool ContainsKey(this ComboBox comboBox, string key)
{
foreach (string existing in comboBox.Items)
{
if (string.Equals(key, existing))
{
return true;
}
}
return false;
}
}
First, they're not equivalent. The 1st sample does a check against txtNewSGroup.Text.Trim(), the 2nd omits trim. Also, the 1st casts everything to a string, whereas the second uses whatever comes out of the iterator. I assume that's an object, or you wouldn't have needed the cast in the 1st place.
So, to be fair, the closest equivalent to the 2nd sample in the LINQ style would be:
if (mbxExistingGroups.Properties.Items.Cast<string>().Contains(txtNewGroup.Text)) {
...
}
which isn't too bad. But, since you seem to be working with old style IEnumerable instead of new fangled IEnumerable<T>, why don't we give you another extension method:
public static Contains<T>(this IEnumerable e, T value) {
return e.Cast<T>().Contains(value);
}
And now we have:
if (mbxExistingGroups.Properties.Items.Contains(txtNewGroup.Text)) {
...
}
which is pretty readable IMO.
I would agree, go with the second one because it will be easier to maintain for anybody else who works on it and when you come back to that in 6-12 months, it will be easier to remember what you were doing.
both of them works for me ..i am wonodering about the performance
I see no one read the question :) I think I see what you're doing (I don't use this language). The first tries to generate the list and test it in one shot. The second does an explicit iteration and can "short circuit" itself (exit early) if it finds the duplicate early on. The question is whether the "all at once" is more efficient due to the language implementation.
The second of the two would perform better, and it would perform the same as other people's samples that use Contains.
The reason why the first one uses an extra trim. plus a conversion to list. so it iterates once for conversion, then starts again to check using exists, and does a trim each time, but will exit iteration if found. The second starts iterating once, has no trim, and will exit if found.
So in short the answer to your question is the second performs much better.
From a performance point of view:
txtNewGroup.Text.Trim()
Do your control interaction/string manipulation outside of the loop - one time, instead of n times.
I imagine that on the WTF's per minute scale, the first would be off the chart. Count the dots, any more than two per line is a potential problem
Related
In C# I get a dictionary dict after reading in a text file that looks kind of like this
#33=CLOSED_SHELL('',(#34,#35,#36,#37,#38,#39));
#34=ADVANCED_FACE('',(#46),#40,.F.);
#35=ADVANCED_FACE('',(#47),#41,.F.);
#36=ADVANCED_FACE('',(#48),#42,.F.);
#37=ADVANCED_FACE('',(#49),#43,.F.);
#38=ADVANCED_FACE('',(#50),#44,.T.);
#39=ADVANCED_FACE('',(#51),#45,.F.);
#40=PLANE('',#127);
#41=PLANE('',#128);
#42=PLANE('',#129);
#43=PLANE('',#130);
#44=PLANE('',#131);
#45=PLANE('',#132);
#46=FACE_OUTER_BOUND('',#52,.T.);
#47=FACE_OUTER_BOUND('',#53,.T.);
#48=FACE_OUTER_BOUND('',#54,.T.);
#49=FACE_OUTER_BOUND('',#55,.T.);
#50=FACE_OUTER_BOUND('',#56,.T.);
#51=FACE_OUTER_BOUND('',#57,.T.);
#52=EDGE_LOOP('',(#58,#59,#60,#61));
#53=EDGE_LOOP('',(#62,#63,#64,#65));
#54=EDGE_LOOP('',(#66,#67,#68,#69));
#55=EDGE_LOOP('',(#70,#71,#72,#73));
#56=EDGE_LOOP('',(#74,#75,#76,#77));
#57=EDGE_LOOP('',(#78,#79,#80,#81));
//... this goes on for a couple of other elements
As you can see each line contains multiple references for another line. Each reference # at the beginning is unique so these are the keys in dict.
So I'm using this method to solve each category step by step:
private void RecursiveMethod(Dictionary<string, string> dict, Step stepObj, List<List<string>> getList, Action<List<string>> setList)
{
foreach(var item in getList.ToList())
{
for(int valuesIndex = 1; valuesIndex < item.Count - 1; valuesIndex++)
{
var key = item[valuesIndex];
string values;
if(dict.TryGetValue(key, out values))
{
setList(SplitValues(values));
}
}
}
}
So my thoughts are to integrate a switch / case statement for each name like this
case "FACE_OUTER_BOUND":
// set list for FACE_OUTER_BOUND...
// ...then call RecursiveMethod(...) again which selects case "EDGE_LOOP" and so on
break;
Does that make sense? Or would I be better off using single methods for each case without recalling the same method?
It really depends on how similar the work will be each time. If as you navigate down the tree of references you need to perform the same navigation on each branch, recursion's your answer.
If after the first navigation the way you handle branches radically changes, use a separate method.
Very generally speaking, write it to be readable and easy to work with first, then change it if performance becomes an issue or you need to split off the functionality drastically.
Remember also that having a method such as ProbeLinesRecursive(int lineNumber) says something to the programmer who reads it, that is "I'll start with the line you give me, then keep going until I run out of lines to probe". This kind of descriptive programming becomes hugely helpful the bigger a project becomes over time.
I got in a discussion with two colleagues regarding a setup for an iteration over an IEnumerable (the contents of which will not be altered in any way during the operation). There are three conflicting theories on which is the optimal approach. Both the others (and me as well) are very certain and that got me unsure, so for the sake of clarity, I want to check with an external source.
The scenario is as follows. We had the code below as a starting point and discovered that some of the hazaas need not to be acted upon. So, starting with the code below, we started to add a blocker for the action.
foreach(Hazaa hazaa in hazaas) ;
My suggestion is as follows.
foreach(Hazaa hazaa in hazaas.Where(element => condition)) ;
One of the guys wants to resolve it by a more explicit form, claiming that LINQ is not appropriate in this case (not sure why it'd be so but he seems to be very convinced). He's solution is this.
foreach(Hazaa hazaa in hazaas) ;
if(condition) ;
The other contra-suggestion is supported by the claim that Where risks to repeat the filtering process needlessly and that it's more certain to minimize the computational workload by picking the appropriate elements once for all by Select.
foreach(Hazaa hazaa in hazaas.Select(element => condition)) ;
I argue that the first is obsolete, since LINQ can handle data objects quite well.
I also believe that Select-ing is in this case equivalently fast to Where-ing and no needless steps will be taken (e.g. the evaluation of the condition on the elements will only be performed once). If anything, it should be faster using Where because we won't be creating an extra instance of anything.
Who's right?
Select is inappropriate. It doesn't filter anything.
if is a possible solution, but Where is just as explicit.
Where executes the condition exactly once per item, just as the if. Additionally, it is important to note that the call to Where doesn't iterate the list. So, using Where you iterate the list exactly once, just like when using if.
I think you are discussing with one person that didn't understand LINQ - the guy that wants to use Select - and one that doesn't like the functional aspect of LINQ.
I would go with Where.
The .Where() and the if(condition) approach will be the same.
But since LinQ is nicely readable i'd prefer that.
The approach with .Select() is nonsense, since it will not return the Hazaa-Object, but an IEnumerable<Boolean>
To be clear about the functions:
myEnumerable.Where(a => isTrueFor(a)) //This is filtering
myEnumerable.Select(a => a.b) //This is projection
Where() will run a function, which returns a Boolean foreach item of the enumerable and return this item depending on the result of the Boolean function
Select() will run a function for every item in the list and return the result of the function without doing any filtering.
while(player.CloseMenu(menuType))
{
}
player.CloseMenu(menuType) will close one menu of the chosen type, or return false if there are none left of that type.
is it ok to use an empty loop like this to close all the menus of a given type?
Be careful when coming up with clever ways of doing things in code. It may save a few keystrokes in the short run, but someday someone else may look at this code and wonder:
What is this even doing?
Ok, I see what it's doing, but why was it done this way?
Is there a compelling reason for this, and should I avoid it so as to not break something else?
Keep in mind, that someone else may very well be you in several months after you've forgotten the details of this code.
Saving a few lines of code isn't really a big deal. Anything that has to be written only once is a finite amount of work. Anything that sows confusion in support going forward produces an unknown and less finite amount of work.
I'd go with more self documentation in case other people need to read it.
The problem is that you have to infer from the fact that the invocation is inferred as a bool to understand.
Maybe if you named it player.IsMoreAfterClose().
or
while(true)
{
bool b = player.CloseMenu(menuType);
if(!b) break;
}
or
bool b = true;
while(b)
{
b = player.CloseMenu(menuType);
}
I would expand on all of these answers and create a method called CloseAllMenus(MenuType menuType). Then you can put whatever kind of ugly implementation in there, and it will be obvious what it is doing when you call it. Your current code doesn't explain what exactly is happening unless you already know that there can be multiple menus of a particular type open, and that this call will only close one of them.
It'll work, obviously, but it makes the code a little hard to read/maintain. You might be better of with the loop condition being a check for any open menus, with the body of the loop closing one.
It's ok to do that as it means do something until certain condition is met. But it's better to incorporate that in the CloseMenu function so that you don't have to repeat this instruction many times and in fact it's a variation of closing menu where you want to close all menus. You can add a boolean argument to the function to indicate if you want to close all menus.
bool CloseMenu(type, closeAll){
if(closeAll)
while(exists(type))
{ close...
else
if(exists(type)
{ close...
}
Maybe the "right" thing to do is invert from While/Close with no body to For/Open with the body doing the Close operation.
foreach(var menu in player.OpenMenus)
menu.Close();
or:
player.OpenMenus.ForEach(c => c.Close());
I break the code of the for loop without using break like I have for loop given below.And when i is 1 or 2 or 3 or any else but if condition is true then loop will be terminated because i will be 5 if the condition is true.And so NO need of break is needed there.Beacause I do not want to use break.I have done like this here.It works.
int myCondition=0;
bool flag=false;
for(int i=0;i<5;i++)
{
if(myCondition==0)
{
flag=true;
}
if(flag)
i=5;
}
But now I want to use foreach loop and in this loop when some condition is true then I want to break the foreach loop code.So what should I do here for breaking the foreach loop code without using break ? Like in the above for loop I have initialize i to 5 when condition is true.In the foreach loop anything like that to do to avoid break.
You should use what's in the language. There's no need to avoid break - just use it. Or to put it another way, "I don't want to use break" is not a good enough justification: if you think you've got a really good reason not to use it, then you should explain that reason. Don't hobble yourself by pretending perfectly reasonable features don't exist, and coming up with convoluted schemes to avoid them.
Don't do it.
Your manipulation of 'i' in the for loop is questionable already. Trying to mess with the iterator in a foreach-loop would be downright dirty. If it compiles at all.
I would write your example with a break or as:
bool myCondition=false;
for(int i=0;i<5 && !myCondition;i++)
{
....
}
In a foreach loop, when you're done before the entire sequence is complete, just call break
This is probably going to get me downvoted... but you should use the break keyword.
Failing that:
foreach(var foo in bar)
{
if(condition)
{
//perform normal loop code
//set condition if required.
}
//otherwise do nothing - the loop will iterate all the way to the end without
//doing anything.
}
You could be more expressive and use if(condition){ /*blah*/}else { continue; } inside the loop - but either way it does the same thing.
You can't do much else to break out of a for each other than:
Use break
Throw an Exception
In general, the 'pattern' you describe here is a code smell. It is NOT a good idea to change the index variable in a for-loop. It can result in unreadable, hard-to-maintain code, especially if the loop grows large.
That being said, why would you not want to use the break keyword. It is meant for this purpose, and whatever downside it has (in your opinion) is still a far better solution than the one you describe here.
Last, I see no way to do the same thing using a foreach loop in a sensible way.
Not using break in your for(;;) loop is a serious stylistic mistake. But you'll get away with it. But not when you use foreach, you have to use the break keyword.
Pay attention to the title of this blog post.
Well, thats why there is this comand "break". I have no reasons why shouldnt you use it.
Your code should absolutely be:
bool myCondition = false;
for(int i=0;i<5;i++)
{
// do stuff
if(myCondition)
break;
}
Not only are you using the commands (i.e. tools) provided by the language, but you are keeping the code very readable, and maintainable. The break command is fundamental to the language.
Trying to come up with some reason not to use break is like doing math on a calculator -- literally, turn the calculator over, get a silver paint marker, and do some math. You are crippling yourself by not using the tools in front of you.
I'm using C# in Visual Studio 2008 with .NET 3.5.
I have a generic dictionary that maps types of events to a generic list of subscribers. A subscriber can be subscribed to more than one event.
private static Dictionary<EventType, List<ISubscriber>> _subscriptions;
To remove a subscriber from the subscription list, I can use either of these two options.
Option 1:
ISubscriber subscriber; // defined elsewhere
foreach (EventType event in _subscriptions.Keys) {
if (_subscriptions[event].Contains(subscriber)) {
_subscriptions[event].Remove(subscriber);
}
}
Option 2:
ISubscriber subscriber; // defined elsewhere
foreach (EventType event in _subscriptions.Keys) {
_subscriptions[event].Remove(subscriber);
}
I have two questions.
First, notice that Option 1 checks for existence before removing the item, while Option 2 uses a brute force removal since Remove() does not throw an exception. Of these two, which is the preferred, "best-practice" way to do this?
Second, is there another, "cleaner," more elegant way to do this, perhaps with a lambda expression or using a LINQ extension? I'm still getting acclimated to these two features.
Thanks.
EDIT
Just to clarify, I realize that the choice between Options 1 and 2 is a choice of speed (Option 2) versus maintainability (Option 1). In this particular case, I'm not necessarily trying to optimize the code, although that is certainly a worthy consideration. What I'm trying to understand is if there is a generally well-established practice for doing this. If not, which option would you use in your own code?
Option 1 will be slower than Option 2. Lambda expressions and LINQ will be slower. I would use HashSet<> instead of List<>.
If you need confirmation about item removal, then Contains has to be used.
EDITED:
Since there is a high probabilty of using your code inside lock statement, and best practice is to reduce time of execution inside lock, it may be useful to apply Option 2. It looks like there is no best practice to use or not-use Contains with Remove.
The Remove() method 'approches O(1)' and is OK when a key does not exist.
But otherwise: when in doubt, measure. Getting some timings isn't that difficult...
Why enumerate the keys when all you're concerned with is the values?
foreach (List<ISubscriber> list in _subscriptions.Values)
{
list.Remove(subscriber);
}
That said, the LINQ solution suggested by Eric P is certainly more concise. Performance might be an issue, though.
I'd opt for the second option. Contains() and Remove() are both O(n) methods, and there's no reason to call both since Remove doesn't throw. At least with method 2, you're only calling one expensive operation instead of two.
I don't know of a faster way to handle it.
If you wanted to use Linq to do this, I think this would work (not tested):
_subscriptions.Values.All(x => x.Remove(subscriber));
Might want to check the performance on that though.