- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Admin
I would react badly as it tried to (a) query, and (b) remove a row out of bounds every time it didn't get an ID match.
Admin
int i = 0; bool found = true;
while((dtModules.Rows[i]["id"].ToString() != ID.ToString()) && (found)) { ++i; if(i == dtModules.Rows.Count) { found = false; } }
if(found) { dtModules.Rows.RemoveAt(i); }
should work better.
Not that I'm a perfectionist at the expense of a joke or anything...
Admin
Don't forget to trap index out of range. And LINQ is only viable if you plan on targeting XP and newer OS's.
Admin
Both your attempts query out of bounds in the while loop condition.
Admin
dtModules.Rows.Remove(dtModules.Rows.First(e => e.ToString() == ID.ToString()));
Admin
You can't fire me, as I'm your bosses son, and your boss has rose tinted spectacles when it comes to me.
What do you do now?
Admin
No no no no no.
Once you have the module list as XML, you should just feed that to an XSLT processor in order to have that find the right line and then write another XML file with the data you need. This makes that whole step both encapsulated and reusable!
Admin
while((found) && (dtModules.Rows[i]["id"].ToString() != ID.ToString())) { ++i; if(i == dtModules.Rows.Count) { found = false; } }
I think.
Admin
That's the one.
Now do it without any keywords.
Admin
Breaking out of a named scope is better than using a goto, in that it doesn't use the 'goto' keyword.
Dogma makes me angry. There are situations where goto is the appropriate tool for the job. The fact that it doesn't place restrictions that make it difficult to use incorrectly does not make it bad.
TRWTF is creating things like named scopes for no apparent purpose other than to avoid 'goto'.
Admin
...bet the programmer was Indian.
:-O
Admin
:start if(i++ < dtModules.Rows.Count && (dtModules.Rows[i]["id"].ToString() != ID.ToString()) { goto start; }
Howdya like dem tomatoes? ;)
Admin
Admin
Admin
To all those people who say that you get an exception if you remove an element from a collection while iterating over it: when do you get the exception? In Java it would be when you ask for the next element, having done the removal, so if you do the removal and immediately break out of the loop you're fine.
Admin
Duh. I fire me.
An Error Occurred
Admin
Maybe the developer was coding for an embedded environment ... one for which the full set of grammar had not been implemented in its compiler?
Admin
Actually, I think he was being sarcastic. But his point wasn't branching: It was structured programming rules. The "break", "return", and "throw" constructs can all be used to violate structured programming rules, strictly speaking.
Admin
I raise: ... if (dtModules.Rows[i]["id"].ToString() == ID.ToString()) { dtModules.Rows.RemoveAt(i); //cause overflow to break out of loop i = 2147483647 + 1;
} ...
Admin
Then I remembered where I was, and decided to just go cry quietly in the corner instead.
Admin
The poor original writer MAY have decided to use that weird exit strategy if he'd read that book about how AT&T lost $110 million because of a misplaced "break" in their phone-system code. You remember the big long-distance blackout of January 1990?
Not that his way is measurably better.
Admin
Real coders use JZ/JNZ.
Admin
WIN :D
Admin
Apart from the magic number there is one other WTF here and that is using linear search. That is, unless the collection is going to be small enough that it won't matter. Certainly if it is anywhere near 34000 elements it is clearly wrong.
Why are so many people commenting on nonsense like using for vs foreach vs std::find or whatever and not noticing the bigger picture?
Admin
[quote user="eViLegion"][quote user="eeth"]Almighty save us all if dtModules ever contains 34598 rows.
But, using a foreach over a collection, then removing an item from that collection during the loop, is also fail. [/quote]
Unless you are
ing out right afterwards.Admin
Another possible inefficiency (that doesn't seem to have been noticed).
Although you might have to call ToString(), you only need to call it once on ID - that never changes, so unless it's pretty much a no-op (i.e. a Get function) call it before the loop.
Admin
http://xkcd.com/378/
Admin
I thought the same thing at first, but tested it to make sure and found that's not the case. The exception won't get called until the next iteration, and since you are breaking after the removal, it would execute ok. HOWEVER, I would still consider using a foreach bad form here as you are setting yourself up for failure later when you decide you don't want to just remove the first, but all instances and remove the break (or the i=somerandomnumber, as the case may be).
Admin
Now that's a good point. Maintainability ftw.
Admin
Add me to the crowd that thinks for is better than foreach here. Even if the foreach approach doesn't cause an error it's implying the wrong thing. I would never code a foreach that terminated in the middle (other than a major error bailout.) Foreach implies that you are covering the whole group!
Admin
Maybe he thought that using magic numbers made hm a coding wizard.
Admin
Admin
Thinking a foreach is better here than a for is a major WTF, and I dare say, even a bigger WTF than the article. There is absolutely NO reason to pick a foreach here.
Also, I thought of a more elegant solution:
Admin
1: C++ can always have ToString(). Not a problem to write one... 3: It may be more complex class, so ToString() methot is acceptable. But of course ir should be opertor==().
Admin
You'll have serious problems if dtModules.Rows.Count is MAX_INT though (where MAX_INT is the maximum possible value to fit into that sized variable).
Admin
Sorry guys, disregard what I just said, I was wrong. Campkev is correct here:
Admin
I'd have done it all in sql. That's what it is there for.
Admin
top...men...
captcha: vulputate to amputate one's vulva
Admin
...as could the modification of control variables, as the case shows. There are people that avoid 'break', 'continue', and 'return' at any cost but achieve the same effect by modifying the state of program control variables. At the end, its the same (e.g. premature loop break) only worse, since it is hidden. My bet is that the guy that wrote the code wanted to avoid using break.
Admin
WIN!!! lol nice one.
Admin
Not sure on the specific language but foreach would normally give you an element reference and not something you can subsequently remove.
If you were writing this in C++ there is find_if which is probably the algorithm you would use here if you have to use linear search at all.You can then do erase() on the iterator if it is not end().
Using find_if might look messy but one is highly unlikely to fall into the trap of calling ID.ToString() on every iteration by using it as you would pass that in as a parameter to something (possibly some horrible bind, yes).
Admin
[quote user="eViLegion"][quote user="eeth"]Almighty save us all if dtModules ever contains 34598 rows.
But, using a foreach over a collection, then removing an item from that collection during the loop, is also fail. [/quote]
LOL WIN!!! nice one... sorry for the dbl post... I thought replying would make it easy to see that my post was related to the above quote... instead it leaves a small unnoticable note that says that this message is a reply to [link]
Admin
Sorry, incorrect. You absolutely can remove an item from a collection while iterating it. It might cause a runtime index exception, but it will not if the loop is exited.
Admin
Admin
If you want to remove multiple items in C++ from a collection, STL provides you std::remove_if. However that doesn't actually remove the items. You need to put collection.erase before it and then collection.end() as the second parameter.
Does this look mad? Yes - but you should learn to use your collections correctly.
Use multimap or map, Then a plain erase(value) will do, and doesn't matter if value doesn't exist. (Can also use hash_map of course, albeit that it isn't standard). You can use map from key to a collection instead of using multimap too (eg map(key,std::list<item>)
If you have multiple indexes on a collection then use std::list as the collection type. Best collection if you are going to remove items from the middle and not invalidate any iterators. Have you indexes point to iterators. Of course if you delete items you must fix all your indexes but once you find the item you can probably find it in all your indexes easily enough. If it's a huge collection and you're removing only a few items, and you want to save on time rather than space this is the way to do it.
Admin
This couldn't be further from the truth. While it's possible for string interning to take place such that multiple strings with the same contents reference the same string object in memory, it's not always the case.
Example App:
using System;
public class MyClass { public static void Main() { string first = "MyString"; string second = "My"; second += "String";
}
Admin
Admin
Time to get your sarcasm detector recalibrated.
Admin