How many"k" are in my textboxes?
I want help for the code that will check a collection of 10 textboxes how many letters"k"are in my textboxes and to see the number in a label1
thank you
Printable View
How many"k" are in my textboxes?
I want help for the code that will check a collection of 10 textboxes how many letters"k"are in my textboxes and to see the number in a label1
thank you
vb.net Code:
Dim CharCounter As Integer = 0 For Each txtbox As TextBox In Me.Controls.OfType(Of TextBox)() Dim c = Aggregate chars In txtbox.Text Where chars = "k"c Into Count() CharCounter += c Next MsgBox("Total number of character k in all textboxes is:" + CharCounter.ToString)
That code will only work on .NET 3.5 wont it though cicatrix?
An alternative that will work in .NET 2.0 would be something like:
vb.net Code:
Dim CharCounter As Integer = 0 For Each txtbox As TextBox In Me.Controls.OfType(Of TextBox)() For Each letter As Char In txtbox.Text If letter = "k"c Then CharCounter += c End If Next Next MessageBox.Show("Total number of character k in all textboxes is:" + CharCounter.ToString)
Yes, my code is for .NET 3.5. I really don't see any reason to continue developing for .NET 2.0 after a newer version is available (and it's free).
LinQ helps enormously and I can't imagine how I managed without it. Still, it's a little more than 'syntactic sugar' but it allows to focus on the main things, not the peculiarities of implementation.
That is a little naive... a lot of people either have an existing program that is using .NET 2.0 that they have to support or they simply dont want to force their users to have to download and install the rather large 3.5 framework (plus SP1) package. A lot more people have .NET 2.0 installed (every Vista user for example as it comes pre-installed) than people have .NET 3.5 installed. I'm sure there are other reasons but those are the first things I think of - after all if there was no reason then every .NET developer would be using 3.5... and that clearly isn't the case.
With memas's here I'm sure he's got vs2008 or 2010 :) Your points are valid and well taken though.
Yeah I'm sure in this particular case using LINQ wont be a problem at all, I just thought it worth mentioning that it requires 3.5 in case the OP was not aware :)
cicatrix
how can i will put the collection of mytextboxes? i dont want all the textboxes
Well, either you should have some criteria or use your custom collection:
...vb.net Code:
Dim myCol As New List(Of TextBox) myCol.Add(Textbox1) myCol.Add(Textbox5)
etc
the rest is the same:
vb.net Code:
Dim CharCounter As Integer = 0 For Each txtbox As TextBox In myCol For Each letter As Char In txtbox.Text If letter = "k"c Then CharCounter += c End If Next Next MessageBox.Show("Total number of character k in all textboxes is:" + CharCounter.ToString)
P.S. If you use VS2003 or VS2005 you should use Chris's example.
cicatrix
1..if i have labels to take the k how will be the code for a group of labels ?
There is a really hideous pun that can be made about this thread, but it may be American only, so I shall spare you all.
Excuse me, kind sirs, but what is 'a pun'? (I know I'm good with my English, but not that good, apparently).
cicatrix
is correct this code because the textbox says 2 and the k are 5
Private Sub Button72_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'HOW MANY K
Dim myCol As New List(Of Label)
myCol.Add(Label201)
myCol.Add(Label200)
myCol.Add(Label199)
myCol.Add(Label198)
myCol.Add(Label197)
myCol.Add(Label196)
myCol.Add(Label195)
myCol.Add(Label193)
myCol.Add(Label190)
myCol.Add(Label189)
myCol.Add(Label188)
myCol.Add(Label185)
myCol.Add(Label181)
myCol.Add(Label178)
Dim CharCounter As Integer = 0
For Each label As Label In Me.Controls.OfType(Of Label)()
Dim c = Aggregate chars In label.Text Where chars = "k"c Into Count()
CharCounter += c
Next
num34TextBox.Text = CharCounter.ToString
End Sub
This is because you're not paying attention to what people tell you.
If you use a custom collection then obviously you should iterate through it.
Here you iterate through ALL texboxes, you need to iterate only throught myCol.
Code:Private Sub Button72_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'HOW MANY K
Dim myCol As New List(Of Label)
myCol.Add(Label201)
myCol.Add(Label200)
myCol.Add(Label199)
myCol.Add(Label198)
myCol.Add(Label197)
myCol.Add(Label196)
myCol.Add(Label195)
myCol.Add(Label193)
myCol.Add(Label190)
myCol.Add(Label189)
myCol.Add(Label188)
myCol.Add(Label185)
myCol.Add(Label181)
myCol.Add(Label178)
Dim CharCounter As Integer = 0
For Each label As Label In MyCol
Dim c = Aggregate chars In label.Text Where chars = "k"c Into Count()
CharCounter += c
Next
num34TextBox.Text = CharCounter.ToString
End Sub
cicatrix the textbox always says 0 zero why?
Hmm, this should work.
Try renaming the label variable:
And it won't probably find 'K' (CAPITAL) - only 'k' (small)Code:...
For Each lbl As Label In MyCol
Dim c = Aggregate chars In lbl.Text Where chars = "k"c Into Count()
CharCounter += c
Next
...
the same thing zero
Some people would call a pun the lowest form of humor, but it is actually just a play on words. For example, I should note that your code will find ALL the ks in a string, including the very rare case where two Ks come one after the other. This is very rare, and could be considered a special K because it refers to serial ks.
Now, in case it is not sold everywhere, Special K is a type of breakfast cereal.
shaggy hiker
why you dont try to help?
its sold here in the UK... and congrats on the terrible pun haha
cicatrix is working the mistake is mine thank you
Sorry, I don't deal in LINQ, so as long as Cicatrix is going down that road and is approaching a solution to the problem, I have nothing to add.
However, I would suggest that doing something like this:
would probably be faster. Haven't tested it, though, but it should match all K or k in the string and return the count of all such matches in the string.Code:For Each label As Label In MyCol
CharCounter += System.Text.RegularExpressions.Regex.Matches(label.Text,"[Kk]").Count
Next
Simpler (and without regex):
Code:c = Aggregate chars In txtbox.Text Where (chars = "k"c Or chars = "K"c) Into Count()
Perhaps, but LINQ isn't fast, so I would question whether or not Regex isn't the faster solution.
Code:Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myCol As New List(Of Label)
For Each l As Label In myCol
num34TextBox.Text = countK(l.Text, False).ToString
Next
End Sub
Dim theCount As Integer = 0
Private Function countK(ByVal inWhat As String, _
Optional ByVal CaseMatters As Boolean = True) As Integer
theCount += inWhat.Count(Function(c) c = "k"c)
If Not CaseMatters Then theCount += inWhat.Count(Function(c) c = "K"c)
Return theCount
End Function
CICATRIX
my mistake was that the k was with capital letter thats why i have problem now that i change the k in code with capital K is working perfect
thank you again
dbasnett
with this code i have errors
relax for today tomorow i hope you are ok and i will ask you a difficult question
memas
Test it for yourself then. Regex was slower
Here's my results:
http://i48.tinypic.com/15g76dw.jpg
vb.net Code:
Imports System.Text.RegularExpressions Public Class Form1 Const MAX_ELEMENTS As Integer = 1000000 Dim rng As New Random Dim btnLINQ, btnREGEX As Button Dim RefCount As Integer = 0 ' For reference purposes Dim TestArray() As String Dim TestList As List(Of String) ' To test Arrays vs Collections issue Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load btnLINQ = New Button With {.Text = "Test LINQ", .Width = 200, .Height = 30, .Left = 10, .Top = 10} btnREGEX = New Button With {.Text = "Test REGEX", .Width = 200, .Height = 30, .Left = 10, .Top = btnLINQ.Bottom + 20} Me.ClientSize = New Size(btnLINQ.Right + 10, btnREGEX.Bottom + 10) Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedDialog Me.Controls.AddRange(New Control() {btnLINQ, btnREGEX}) Me.Text = "LINQ vs REGEX" PrepareTestObjects() AddHandler btnLINQ.Click, AddressOf TestLINQ AddHandler btnREGEX.Click, AddressOf TestREGEX End Sub Private Sub PrepareTestObjects() btnLINQ.Enabled = False btnREGEX.Enabled = False RefCount = 0 TestList = New List(Of String) ReDim TestArray(MAX_ELEMENTS - 1) Dim x, c As Integer Randomize(Now.Ticks) For x = 0 To MAX_ELEMENTS - 1 Dim l As Integer = rng.Next(10, 21) ' make a random length Dim element As String = "" For c = 0 To l Dim randomChar As Char = Chr(rng.Next(33, 123)) ' random character from "!" to "z" element += randomChar If randomChar = "k"c Or randomChar = "K"c Then RefCount += 1 ' We'll know for sure how many k's here Next TestArray(x) = element TestList.Add(element) Next btnLINQ.Enabled = True btnREGEX.Enabled = True End Sub Private Sub TestLINQ(ByVal sender As Object, ByVal e As EventArgs) Dim KCount As Integer = 0 Dim t As DateTime = Now For Each st In TestArray Dim Cnt = Aggregate chars In st Where (chars = "k"c Or chars = "K"c) Into Count() KCount += Cnt Next Dim ArrayTestDuration As TimeSpan = Now - t KCount = 0 t = Now For Each st In TestList Dim Cnt = Aggregate chars In st Where (chars = "k"c Or chars = "K"c) Into Count() KCount += Cnt Next Dim ListTestDuration As TimeSpan = Now - t Dim ResultsStr As String = String.Format( _ "Test on {4} elements of random strings using LINQ:{1}Test on array:{3}{0:mm:ss.FFF} ms {1}Test on list:{3}{2:mm:ss.FFF} ms{1}Found elements:{3}{5}{1}Reference elements:{3}{6}", _ New Object() {ArrayTestDuration, Environment.NewLine, ListTestDuration, ControlChars.Tab, MAX_ELEMENTS, KCount, RefCount}) MsgBox(ResultsStr, MsgBoxStyle.Information, "Test results for LINQ") End Sub Private Sub TestREGEX(ByVal sender As Object, ByVal e As EventArgs) Dim KCount As Integer = 0 Dim t As DateTime = Now For Each st In TestArray KCount += Regex.Matches(st, "[Kk]").Count Next Dim ArrayTestDuration As TimeSpan = Now - t KCount = 0 t = Now For Each st In TestList KCount += Regex.Matches(st, "[Kk]").Count Next Dim ListTestDuration As TimeSpan = Now - t Dim ResultsStr As String = String.Format( _ "Test on {4} elements of random strings using REGEX:{1}Test on array:{3}{0:mm:ss.FFF} ms {1}Test on list:{3}{2:mm:ss.FFF} ms{1}Found elements:{3}{5}{1}Reference elements:{3}{6}", _ New Object() {ArrayTestDuration, Environment.NewLine, ListTestDuration, ControlChars.Tab, MAX_ELEMENTS, KCount, RefCount}) MsgBox(ResultsStr, MsgBoxStyle.Information, "Test results for REGEX") End Sub End Class
So there I was, going to test the results, and my machine locked up. Numerous times I have tried to test regex and had this happen. Basically my code timer calls the init code once, and then each of the tests hundreds of thousands of times. I must be missing something.
Code:Dim testSTR As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim myCount As Integer = 0
Private Function TestCase1() As Boolean 'One
'Test One Code Follows
myCount = Aggregate chars In testSTR Where (chars = "k"c Or chars = "K"c) Into Count()
'End Test One Code
Return True
End Function
'
Private Function TestCase2() As Boolean 'Two
'Test Two Code Follows
myCount = System.Text.RegularExpressions.Regex.Matches(testSTR, "[Kk]").Count
'End Test Two Code
Return True
End Function
'
Private Sub _init()
'Code needed to get the Test to run. NOT part of the timing.
testSTR &= testSTR.ToLower
testSTR &= testSTR
'Only called once!!!
End Sub
Yup, LINQ turns out to beat both Regex and the old fashioned looping through the characters. I have seen cases where LINQ was slower, but it is not in this case.
However, I haven't used LINQ much, nor have I used the type inference that is present in the LINQ example. When I copied that into my testapp, I found that type inference simply wasn't working in that app, despite using VS2008 targeting the 3.5 framework. Is there something else that I need to set?
Are you absolutely sure that the most optimized form of looping possible couldn't beat it? (Normally I would test it, but I have VS 2005.)
vb Code:
Dim i As Integer = 0, count As Integer = 0, kL As Char = "k", kU As Char = "K" While i < str.Length If str.Chars(i) = kL OrElse str.Chars(i) = kU Then count += 1 i += 1 End While
sort of thing? Or call ToCharArray() first? There are just too many different ways to use the simple loop.
Yeah, I tested that one, too. LINQ beat it handily. I didn't compare it directly to Regex, but they were in the same vicinity.
haven't read all the posts but:
vb Code:
MsgBox((From xItem In asd Where LCase(xItem) = "k").Count)
and actually linq is always faster ... except in cases where you need to evaluate the same thing multiple times... such as:
From xItem in asd where xItem.Somefunction() = "a" or xItem.Somefunction() = "b"
as Somefunction will be evaluated 2x where in a loop you could store this in a variable... of course u could do it like this:
From xItem In (From xItem In asd Select xItem, xItem.Somefunction) Where xItem.Somefunction = "a" Or xItem.Somefunction = "b" Select xItem.xItem
Thus only evaluating it in the inner linq query 1 time.