Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

parse string of IDs for count, then list name & count

Posted on 2011-09-20
5
212 Views
Last Modified: 2012-05-12
Experts,

I need this in VB.NET, and I'm getting desperate...

This was my first attempt at this question, my own approach is a complete failure - I NEED to store the card data in the app, so as an enumeration? (the card data is static, does not change). Dictionary? Please give a complete answer...

http://www.experts-exchange.com/Programming/Languages/.NET/Q_27291428.html

This is another cross-posted version of this question I also have open, but I'm getting C# answers that I cannot use. I'm perfectly happy to award points for both (though that's prolly not allowed):

http://www.experts-exchange.com/Programming/Languages/.NET/Q_27317071.html

I have a string that looks like the following, let's call it strCards = "1,1,2,2,2,3,1,3,34,34,34,23,23,23,2,4,4,4,6,6,6,1,1,1,99,99,34,34"

This string is always comma seperated.

These are card_ids.

The card data looks like this:

id       Card Name
1          cardone
2          cardtwo
3          cardthree
4          cardfour
5          cardfive
6          cardsix
etc

I need to be able to parse the strCard and list the CardName and the number of times that card_id appears in strCards in a listbox, so:

cardone            6
cardtwo            3
cardthree          2
cardfour            3
cardsix              3
...
cardninetynine  2

and so on...

0
Comment
Question by:crafuse
  • 3
  • 2
5 Comments
 
LVL 25

Expert Comment

by:Luis Pérez
ID: 36567235
Ok, here's my solution.

I've used a ListView instead a ListBox for the results, as you can add different columns to it. So create a new ListView in your form and call it "lvwCards". Add two columns to your lvwCards ListView. First column must show the text "Card" in the header, and second column must show "Times". Set the View property of the ListView to "Details" value.

Now we're going to fill the lvwCards. Here's my code:

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim strCard As String = "1,1,2,2,2,3,1,3,34,34,34,23,23,23,2,4,4,4,6,6,6,1,1,1,99,99,34,34"

        'Split the string into separate numbers
        Dim cards() As String = strCard.Split(",")

        'Iterate thru the array of numbers
        For Each card As String In cards
            'Get the card name corresponding to this number
            Dim cardName As String = getCardName(card)

            'Get the item with that card name
            Dim item As ListViewItem = Me.lvwCards.FindItemWithText(cardName)

            'If the item isn't found, create a new item for this card name
            If IsNothing(item) Then
                item = Me.lvwCards.Items.Add(cardName)

                'By default, assign "0" to the number of times
                item.SubItems.Add("0")
            End If

            'Append 1 to the number of times this card appears
            item.SubItems(1).Text = (CInt(item.SubItems(1).Text) + 1).ToString
        Next
    End Sub

Open in new window


The getCardName function is as follows (obviosly I've only added card names for the card numbers you put in your example; you must fill with all the possible card name-card number pairs).

    Private Function getCardName(ByVal card As String) As String
        Select Case card
            Case "1"
                Return "cardone"
            Case "2"
                Return "cardtwo"
            Case "3"
                Return "cardthree"
            Case "4"
                Return "cardfour"
            Case "6"
                Return "cardsix"
            Case "34"
                Return "cardthirtyfour"
            Case "23"
                Return "cardtwentythree"
            Case "99"
                Return "cardninetynine"
        End Select
    End Function

Open in new window


Hope that helps. You can see a preview of the results in the attached image. Results of the code.
0
 
LVL 25

Expert Comment

by:Luis Pérez
ID: 36567247
Storing the number-name card pairs into a function is not a very elegant but working solution. Obviously there are many other methods, and you must consider them specially if is suitable that in the future more cards can appear. In that case you would need an external card data source: a database, or xml file, or INI file...
0
 

Author Comment

by:crafuse
ID: 36567604
Thanks Roland!

Perfect & simple & elegant. However, I do have need for a listbox & not a listview (which i've never used before). The reason for that is because i'm calling this routine later to populate a richtextbox. but no problem, i'll look at this tomorrow and respond.

below is my own un-expert effort. perhaps you could take a look at it - i can't seem to get the last item to be listed without that last pass through the data - what am i doing wrong?

would it be too much trouble for you to change your code for a listbox? i don't care about column alignment - i'm using fixed fonts anyways, so i can manipulate things to make it look good...

thanks...

crafuse
Public Enum Cards
        CardOne = 1
        CardTwo = 2
        CardThree = 3
        CardFour = 4
        CardFive = 5
        CardTwentyFive = 25
        CardThirtyFour = 34
        CardNinja = 99
    End Enum

    Public Function MyEnumName(ByVal EnumIndex As Cards) As String
        MyEnumName = [Enum].GetName(GetType(Cards), EnumIndex)
    End Function

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        strLibraryList = "1,1,1,34,2,2,4,4,99,99,99,34,4,4,4,4,99,99,99,99,1,1,34,34,34,34,34,34,1,1"

        If strLibraryList <> "" Then
            Dim MyArray As New ArrayList()
            Dim values() As String = strLibraryList.ToString.Split(",")
            'Dim int As Integer = 1
            Dim int As Integer
            Dim total As Integer

            MyArray.AddRange(values)
            MyArray.Sort()

            Dim b As Integer
            For b = 0 To MyArray.Count - 1
                If MyArray(b) <> int AndAlso total > 0 Then

                    Dim CardSQL As String
                    Dim strCardName As String


                    strCardName = MyEnumName(int)

                    If strCardName <> "" Then
                        ListBox1.Items.Add(strCardName.PadRight(32, " ") & " " & total)
                    Else
                        ListBox1.Items.Add("No Cardname in DB" & " " & total)
                    End If

                    total = 1
                    int = MyArray(b)
                Else
                    total += 1
                    int = MyArray(b)
                End If
            Next b
            'here we try and capture the last item that is not being added to the listbox

            If b = MyArray.Count AndAlso total > 0 Then
                Dim CardSQL As String
                Dim strCardName As String

                
                strCardName = MyEnumName(int)

                If strCardName <> "" Then
                    ListBox1.Items.Add(strCardName.PadRight(32, " ") & " " & total)
                Else
                    ListBox1.Items.Add("No Cardname in DB" & " " & total)
                End If
                
            End If

        End If
    End Sub

Open in new window

0
 
LVL 25

Accepted Solution

by:
Luis Pérez earned 500 total points
ID: 36567759
Ok, so you need a ListBox. With this requirement my previous code does not work, because it relies directly on the ListView to find the number of times a card appears. But let's change it a bit.

Instead of that, you can use a Dictionary(Of String, Integer) to hold the cards and the number of times each card appears. This Dictionary is nothing but a collection of integer values, each one of them with a string key, so we'll use the card number (in string format) as the string key, and for each card will hold the number of times it appears.

Here's the modified code:

        Dim strCard As String = "1,1,2,2,2,3,1,3,34,34,34,23,23,23,2,4,4,4,6,6,6,1,1,1,99,99,34,34"

        'Split the string into separate numbers
        Dim cards() As String = strCard.Split(",")

        'This dictionary will hold each card and the number of times it appears
        Dim repetitions As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)

        'Iterate thru the array of numbers
        For Each card As String In cards
            'See if the card is already in the dictionary
            'If not, add a new dictionary entry with card number and 0 repetitions
            If (Not repetitions.ContainsKey(card)) Then
                repetitions.Add(card, 0)
            End If

            'Append 1 to the number of times this card appears
            repetitions.Item(card) += 1
        Next

        'Put the results in a ListBox
        For Each card As String In repetitions.Keys
            Dim cardName As String = getCardName(card)
            Dim strOutput As String = cardName + New String(" ", 25 - cardName.Length) + repetitions.Item(card).ToString
            Me.ListBox1.Items.Add(strOutput)
        Next

Open in new window


You are doing it well using an Enum to store the card number-card name pair. So you can replace my getCardName function call by your MyEnumName easily.

Hope that helps.
0
 

Author Comment

by:crafuse
ID: 36567960
Roland -

this is great. it works nice. i'll go over it in more detail tomorrow - i have to get to know the following a bit better:

Dim strOutput As String = cardName + New String(" ", 25 - cardName.Length) + repetitions.Item(card).ToString

Thanks tons,

crafuse
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Get number of Files in Directory and Sub Directories 2 48
Expression Evaluater 3 38
VB.NET String Settings and Temp Folder Question 3 55
Visual studio 2015 1 22
This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question