Count array character matches

TomL

Member
Joined
Sep 22, 2009
Messages
13
Programming Experience
Beginner
I have an array of items where i have separated the first two characters, which in my case are ID tags. I have populated my CLBox and the output is like this

VB.NET:
AA
Aa
BB
bb
C1
20
3c
AA
BB
C1
C1
etc, etc

I would like to count the matching tags and show the totals like this

VB.NET:
AA=2
Aa=1
BB=2
bb=1
C1=3
etc, etc

At the moment my code looks like this

VB.NET:
Private Sub Button1_Click()

        For i As Integer = 0 To ListBox1.SelectedItems.Count - 1
            Using r = New StreamReader(ListBox1.SelectedItems(i).ToString)

                Dim TshirtList As String = r.ReadLine
                While Not TshirtList Is Nothing
                    Dim IDTag() As String = TshirtList.Split("-")
                    
                    Dim Tags As String = IDTag(1).Substring(0, 2)
 
                    CheckedListBox1.Items.Add(Tags)
                    TshirtList = r.ReadLine

What would the process be to do this, would i need to create a reference list or stringbuilder for all the tags(there is about 3000 tags) or would it be possible to loop through and count the matches. I declared the Tags thinking that i could do something from there.

Any help would be appreciated
 
Assuming .NET 3.5, the easiest way to do this is using LINQ:
VB.NET:
Dim allItems As String() = {"AA", "Aa", "BB", "bb", "C1", "20", "3c", "AA", "BB", "C1", "C1"}
Dim itemCounts = (From item In allItems _
                  Group item By item Into Count() _
                  Select item & "=" & Count).ToArray()

For Each count In itemCounts
    MessageBox.Show(count)
Next
 
That works nice on its own, i cant however seem to adapt it when i have an input file

I already have my string

VB.NET:
Dim Tags As String = IDTag(1).Substring(0, 2)

Substituting that with 'allitems' splits the results further into single lines

A=1
A=1
A=1
a=1

The input file can change and have 200 lines or 3000 lines, depending on circumstances.

I'm not familiar with LINQ so not sure how i can adapt what i have here
 
Sorry a bit vague

I load textfiles to listbox, these textfiles are stock data and are listed like so

VB.NET:
blackshort-bs8547
whiteshort-ws7854
vespashort-vs887756
vespalong-vl8774442
redcrop-rc4551033
nikeblueR-nb4875552
nikeblueE-nb458777
stockyellow-10sy4555
stockorange-20so547885
whiteshortM-ws88554
vespashortM-vs985544
vespalongE-vl45114
redcropF-rc65841
nikeblueR-nb215445
nikeblueE-nb854455
stockyellowF-10984441
stockorangeC-20so585
adidasA-AA41112

These files can be various line lengths, what i want to do is get the IDtag which is the first 2 chracters after the deliminater and have a total of each Idtag in the checkedlistbox. Hence the line of code from my full code in the first post

VB.NET:
Dim Tags As String = IDTag(1).Substring(0, 2)

Your LINQ code populated the CLBox and did a count on the string 'alltems' which is what i am looking for, but to work with the inputed textfiles from the listbox

hope that makes sense
 
With LINQ the logic is exactly the same. You simply change what you group the items by:
VB.NET:
Dim originalText = "blackshort-bs8547" & Environment.NewLine & _
                   "whiteshort-ws7854" & Environment.NewLine & _
                   "vespashort-vs887756" & Environment.NewLine & _
                   "vespalong-vl8774442" & Environment.NewLine & _
                   "redcrop-rc4551033" & Environment.NewLine & _
                   "nikeblueR-nb4875552" & Environment.NewLine & _
                   "nikeblueE-nb458777" & Environment.NewLine & _
                   "stockyellow-10sy4555" & Environment.NewLine & _
                   "stockorange-20so547885" & Environment.NewLine & _
                   "whiteshortM-ws88554" & Environment.NewLine & _
                   "vespashortM-vs985544" & Environment.NewLine & _
                   "vespalongE-vl45114" & Environment.NewLine & _
                   "redcropF-rc65841" & Environment.NewLine & _
                   "nikeblueR-nb215445" & Environment.NewLine & _
                   "nikeblueE-nb854455" & Environment.NewLine & _
                   "stockyellowF-10984441" & Environment.NewLine & _
                   "stockorangeC-20so585" & Environment.NewLine & _
                   "adidasA-AA41112"
Dim lines = originalText.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
Dim upperBound = lines.GetUpperBound(0)
Dim idTags(upperBound)() As String

For index As Integer = 0 To upperBound
    idTags(index) = lines(index).Split("-"c)
Next

Dim itemCounts = (From idTag In idTags _
                  Group idTag By code = idTag(1).Substring(0, 2) Into Count() _
                  Select code & "=" & Count).ToArray()

For Each count In itemCounts
    MessageBox.Show(count)
Next
 
Yes i see, the terminology is the same

but how would i apply this to openfiles dialogue, i have many textfiles to go through, and at the moment i can load the filenames into my listbox, select one or multiple files and populate the list box with the idtags.

The textfiles data is always changing, so its not something that i can hard code

I realize that to readin the files and allocate to string gives me a starting string for 'originaltext' and i have done that, but I am getting results back as so

bs=1
bs=1
bs=1
vs=1

without counting totals
 
In my code above I did this:
VB.NET:
Dim lines = originalText.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
If your data is coming from a file in that same form then you just do this:
VB.NET:
Dim lines = IO.File.ReadAllLines("file path here")
and then everything that follows is the same. If your data is in some different form then you adjust the code accordingly, but the principle is exactly the same.
 
Is it possible to sort the output by highest quantity? would that need to be done before populating or can it be done after, with CLBox control

aa=5
as=4
ee=3
ff=2
etc.etc

If so i can research a bit and try to do it
 
You would then apply a OrderBy/Descending to the Linq query, check out the samples and try for yourself first: 101 LINQ Samples
 
VB.NET:
Dim itemCounts = (From idTag In idTags _
                  Group idTag By code = idTag(1).Substring(0, 2) Into Count() _
                  Order By Count Descending _
                  Select code & "=" & Count).ToArray()
If you want to make use of LINQ then I suggest that you go to MSDN and do some reading. There are lots of examples and explanations available.
 
Back
Top