|
|
Try Expresso, its a very handy tool if your going to be doing regular expressions. It also contains a small library of reg. expressions for common problems.
Here[^]
Mike
|
|
|
|
|
I admit to ignorance and some laziness. There.
Never having written a Linq expression, (or in this case, is it a simple lambda expression?) I'm humbly asking for an example, as I'd like to start learning this feature.
Here's the code. It should be obvious what I'm trying to do.
bool bad=false;
foreach (char c in failure.ToCharArray())
{
if (!Char.IsDigit(c) && !Char.IsWhiteSpace(c))
{
bad = true;
break;
}
}
Thanks!
Marc
|
|
|
|
|
Well I don't know how to write the LINQ but I would have posted the question in the LINQ forum. What a Nub
led mike
|
|
|
|
|
led mike wrote: Well I don't know how to write the LINQ but I would have posted the question in the LINQ forum. What a Nub
We have a Linq forum? Oh! You're right. What a Nub I am!
Marc
|
|
|
|
|
You cant do that in Linq (because of the break statement) But you can do something with same effect.
<font color="Blue">string</font> failure <font color="DarkBlue">=</font> <font color="Maroon">"fob"</font><font color="DarkBlue">;</font>
<font color="Blue">bool</font> bad <font color="DarkBlue">=</font> <font color="DarkBlue">(</font><font color="Blue">from</font> c <font color="Blue">in</font> failure
<font color="Blue">where</font> <font color="DarkBlue">!</font><font color="DarkBlue">(</font><font color="Blue">char</font><font color="DarkBlue">.</font>IsWhiteSpace<font color="DarkBlue">(</font>c<font color="DarkBlue">)</font> <font color="DarkBlue">||</font> <font color="Blue">char</font><font color="DarkBlue">.</font>IsDigit<font color="DarkBlue">(</font>c<font color="DarkBlue">)</font><font color="DarkBlue">)</font>
<font color="Blue">select</font> c<font color="DarkBlue">)</font><font color="DarkBlue">.</font>Count<font color="DarkBlue">(</font><font color="DarkBlue">)</font> <font color="DarkBlue">></font> <font color="Red">0</font><font color="DarkBlue">;</font>
[update] fixed the query [update]
modified on Friday, September 12, 2008 11:44 AM
|
|
|
|
|
I was wondering about that, because of the break statement.
So. That's, umm, disappointing. I certainly don't want to process a million character string if the first char in the string is 'A'.
Marc
|
|
|
|
|
See my reply to myself
|
|
|
|
|
Actually, you could still use the Linq functions, but not a query pre se. The Contains Any function takes a predicate.
bad = failure.Any(c => !(char.IsWhiteSpace(c) || char.IsDigit(c)));
[update] fixed the missing ! part [update]
modified on Friday, September 12, 2008 11:41 AM
|
|
|
|
|
leppie wrote: Any function takes a predicate.
Coolness! That's what I was looking for.
Thank you!
Marc
|
|
|
|
|
leppie wrote: bad = failure.Any(c => char.IsWhiteSpace(c) || char.IsDigit(c));
Except, wouldn't the logic be:
bool bad = failure.Any(c => (!char.IsWhiteSpace(c) && !char.IsDigit(c)));
Marc
|
|
|
|
|
Yeah I forgot the ! part in front of the condition. It is fixed now.
|
|
|
|
|
From your original post I assume you want to do some sort of processing on the valid lines so i think you can use the Where method.
foreach (var line in allLines.Where(s => s.Any(c => !(char.IsWhiteSpace(c) || char.IsDigit(c)))))
{ }
You might find the Select method useful, something like
allLines.Where(s => s.Any(c => !(char.IsWhiteSpace(c) || char.IsDigit(c)))).Select(s => s.Length);
Eslam Afifi
modified on Friday, September 12, 2008 1:04 PM
|
|
|
|
|
Marc Clifton wrote: So. That's, umm, disappointing. I certainly don't want to process a million character string if the first char in the string is 'A'.
Technically it would be possible for the Count function to break early, if it could infer the resulting comparison, thus resulting in an Any function as per the other example.
[update] I did a test, it does not appear to do it for a string enumerable, I do however believe that SQL will be optimized if running the same query over a database source. [update]
|
|
|
|
|
leppie wrote: I do however believe that SQL will be optimized if running the same query over a database source.
Huh? I'm LINQless so I have no idea what that means.
led mike
|
|
|
|
|
led mike wrote: Huh? I'm LINQless so I have no idea what that means.
Linq has the ability to change QueryProviders based on what is being queried. So calling Linq of a database source, will translate the Linq query into SQL. Once iterating over the query, the SQL will be executed.
So what it comes down to is that SQL should be 'strong' enough to optimize a Count(select * from table where i = 0) > 0 expression into something that resembles the Any function.
That probably does not make any sense
|
|
|
|
|
leppie wrote: That probably does not make any sense
Whew, I thought it was me.
So then where does some sort of performance gain come into effect in the current example? I mean how are the expression trees etc., going to faster than code like:
char[] chars = failure.ToCharArray();
bool bad = false;
for (int n = 0; !bad && n < chars.Length; n++)
if (!Char.IsDigit(chars[n]) && !Char.IsWhiteSpace(chars[n]))
bad = true;
led mike
|
|
|
|
|
led mike wrote: So then where does some sort of performance gain come into effect in the current example? I mean how are the expression trees etc., going to faster than code like:
It's not. It could be equal or slower. But it's easier to write failure.Any(c => !(char.IsWhiteSpace(c) || char.IsDigit(c)))
I am willing to bet, that code would run close to your snippet.
|
|
|
|
|
leppie wrote: But it's easier to write
By easier to write you mean less key presses?
led mike
|
|
|
|
|
leppie wrote: But you can do something with same effect.
Meaning it will traverse the entire string. It will be ok for short strings, or if you do not expect many failures.
A better solution is to use Regex, IMO.
|
|
|
|
|
Damn - you beat me to it. I should have known.
|
|
|
|
|
You could do this as:
string failure = "123 512512512 1";
bool bad = (from p in failure.ToCharArray()
where !char.IsDigit(p) && !char.IsWhiteSpace(p)
select p).Count() > 0;
Console.WriteLine("{0}\n", bad); I wouldn't really recommend it though because you are going to get a lot of work going on there if the array becomes really large. What I would recommend instead is using a regular expression to handle this. While LINQ is decent at a lot of tasks, there are times when it's a lot better to use other technologies which are more suited to the task.
|
|
|
|
|
Hopefully a simple question. I am creating an output file, and when finished I need to go back and update the header row with a row count in position 10. I am using StreamWriter.
Here is a the original output file, and I would like to replace the "0000" with "0005" on line one:
Habcdefghi0000tuvwxyz
detail one
detail two
detail three
detail four
detail five
Here is the code:
FileStream fs = new FileStream("c:\\textFile.txt", FileMode.Open, FileAccess.ReadWrite);
using(StreamWriter sw = new StreamWriter(fs))
{
Console.WriteLine("Current Position: {0}",sw.BaseStream.Position);
sw.BaseStream.Seek(10, SeekOrigin.Begin);
Console.WriteLine("Current Position: {0}", sw.BaseStream.Position);
sw.Write("0005");
}
That works - header now looks as follows:
Habcdefghi0005tuvwxyz
However, when I try to update another value on the header (at position 1)...things get real screwy. Here is the updated code:
FileStream fs = new FileStream("c:\\textFile.txt", FileMode.Open, FileAccess.ReadWrite);
using(StreamWriter sw = new StreamWriter(fs))
{
Console.WriteLine("Current Position: {0}",sw.BaseStream.Position);
sw.BaseStream.Seek(10, SeekOrigin.Begin);
Console.WriteLine("Current Position: {0}", sw.BaseStream.Position);
sw.Write("0005");
sw.BaseStream.Seek(1, SeekOrigin.Begin);
Console.WriteLine("Current Position: {0}", sw.BaseStream.Position);
sw.Write("Test");
}
This time, the WriteLine output appears correct (positions: 0, 10, and 1), but the header looks like this:
H0005Testi0000tuvwxyz
I read somewhere that the buffers might need to get flushed/reset, but can't seem to find that method. Also, is there a better way to update the header row?
Thanks for any advice that can be offered!
|
|
|
|
|
sw.AutoFlush = true; ?
Alan.
|
|
|
|
|