none
Need help on Listbox duplicate values RRS feed

  • Question

  • Greetings,

    I have 2 listboxes with the same number of items :

    Each item in listbox1 (the left one) corresponds to the same item in listbox2. So corresponding value of 123 is 600.

    There might be duplicate values in the first listbox. For example, in the picture above, 123 is repeated twice.

    I need to keep the first occurrence of a value (the first 123 , index = 0) and delete the other duplicate values, but on this condition : Corresponding values (listbox2) of the deleted items (listbox1) must be added to the value (listbox2) of the only existing occurrence of a value (123).

    So here would be the result :

    I already know how to find duplicate values in a listbox, but need help on adding values to listbox2 :

     For Row As Int16 = 0 To inputList.Items.Count - 2
                For RowAgain As Int16 = inputList.Items.Count - 1 To Row + 1 Step -1
                    If inputList.Items(Row).ToString = inputList.Items(RowAgain).ToString Then
                        ' RowAgain is duplicate
                    End If
                Next
            Next

    Saturday, March 28, 2020 9:18 PM

Answers

  • Hi

    Here is one way. I just altered your code a little, and added a litt;le.

    Initial

    Result

    ' Form1 with ListBox1
    ' ListBox2 and Button1
    Option Strict On
    Option Explicit On
    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ListBox1.Items.AddRange({123, 145, 100, 145, 151, 123, 160, 145})
        ListBox2.Items.AddRange({600, 145, 120, 145, 800, 50, 40, 145})
      End Sub

      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rowtodelete As New List(Of Integer)
        For Row As Integer = 0 To ListBox1.Items.Count - 2
          For RowAgain As Integer = ListBox1.Items.Count - 1 To Row + 1 Step -1
            If ListBox1.Items(Row).ToString = ListBox1.Items(RowAgain).ToString Then
              ' RowAgain is duplicate
              ListBox2.Items(Row) = CInt(ListBox2.Items(Row)) + CInt(ListBox2.Items(RowAgain))
              If Not rowtodelete.Contains(RowAgain) Then rowtodelete.Add(RowAgain)
            End If
          Next
        Next
        rowtodelete.Sort()

        If rowtodelete.Count > 0 Then
          For i As Integer = rowtodelete.Count - 1 To 0 Step -1
            ListBox1.Items.RemoveAt(rowtodelete(i))
            ListBox2.Items.RemoveAt(rowtodelete(i))
          Next
        End If
      End Sub

    End Class


    Regards Les, Livingston, Scotland





    • Edited by leshay Saturday, March 28, 2020 10:18 PM Added images
    • Marked as answer by Kevin993 Saturday, March 28, 2020 10:25 PM
    Saturday, March 28, 2020 10:00 PM

All replies

  • Hi

    Here is one way. I just altered your code a little, and added a litt;le.

    Initial

    Result

    ' Form1 with ListBox1
    ' ListBox2 and Button1
    Option Strict On
    Option Explicit On
    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ListBox1.Items.AddRange({123, 145, 100, 145, 151, 123, 160, 145})
        ListBox2.Items.AddRange({600, 145, 120, 145, 800, 50, 40, 145})
      End Sub

      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rowtodelete As New List(Of Integer)
        For Row As Integer = 0 To ListBox1.Items.Count - 2
          For RowAgain As Integer = ListBox1.Items.Count - 1 To Row + 1 Step -1
            If ListBox1.Items(Row).ToString = ListBox1.Items(RowAgain).ToString Then
              ' RowAgain is duplicate
              ListBox2.Items(Row) = CInt(ListBox2.Items(Row)) + CInt(ListBox2.Items(RowAgain))
              If Not rowtodelete.Contains(RowAgain) Then rowtodelete.Add(RowAgain)
            End If
          Next
        Next
        rowtodelete.Sort()

        If rowtodelete.Count > 0 Then
          For i As Integer = rowtodelete.Count - 1 To 0 Step -1
            ListBox1.Items.RemoveAt(rowtodelete(i))
            ListBox2.Items.RemoveAt(rowtodelete(i))
          Next
        End If
      End Sub

    End Class


    Regards Les, Livingston, Scotland





    • Edited by leshay Saturday, March 28, 2020 10:18 PM Added images
    • Marked as answer by Kevin993 Saturday, March 28, 2020 10:25 PM
    Saturday, March 28, 2020 10:00 PM
  • Hello,

    Here is an example that finds/removes the duplicate and then adds it to the second listbox via GroupBy in a lambda statement.

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim results = ListBox1.
                    Items.Cast(Of String).
                    Distinct().Select(Function(item) item).
                    ToArray()
    
            Dim diff = ListBox1.Items.Cast(Of String).
                    ToArray().
                    GroupBy(Function(x) x).
                    Select(Function(x) New With {Key .key = x.Key, Key .Count = x.Count()}).
                    Where(Function(x) x.Count > 1)
    
            ListBox1.Items.Clear()
            ListBox1.Items.AddRange(results)
    
            For Each item In diff
                ListBox2.Items.Add(item.key)
            Next
    
        End Sub
    End Class
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Saturday, March 28, 2020 10:05 PM
    Moderator
  • Hi

    Here is one way. I just altered your code a little, and added a litt;le.

     ' Form1 with ListBox1
    ' ListBox2 and Button1
    Option Strict On
    Option Explicit On
    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ListBox1.Items.AddRange({123, 145, 100, 151, 123, 160, 145})
        ListBox2.Items.AddRange({600, 145, 120, 800, 50, 40, 145})
      End Sub

      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rowtodelete As New List(Of Integer)
        For Row As Integer = 0 To ListBox1.Items.Count - 2
          For RowAgain As Integer = ListBox1.Items.Count - 1 To Row + 1 Step -1
            If ListBox1.Items(Row).ToString = ListBox1.Items(RowAgain).ToString Then
              ' RowAgain is duplicate
              ListBox2.Items(Row) = CInt(ListBox2.Items(Row)) + CInt(ListBox2.Items(RowAgain))
              rowtodelete.Add(RowAgain)
            End If
          Next
        Next
        If rowtodelete.Count > 0 Then
          For i As Integer = rowtodelete.Count - 1 To 0 Step -1
            ListBox1.Items.RemoveAt(rowtodelete(i))
            ListBox2.Items.RemoveAt(rowtodelete(i))
          Next
        End If
      End Sub

    End Class


    Regards Les, Livingston, Scotland



    I guess when there are more than 2 occurrences of duplicates, your code stops functioning (not continuing to find, remove and add), 

    What about this :

      Dim rowtodelete As Integer = -1
            For Row As Integer = 0 To ListBox1.Items.Count - 2
                For RowAgain As Integer = ListBox1.Items.Count - 1 To Row + 1 Step -1
                    If ListBox1.Items(Row).ToString = ListBox1.Items(RowAgain).ToString Then
                    
                        ListBox2.Items(Row) = CInt(ListBox2.Items(Row)) + CInt(ListBox2.Items(RowAgain))
                        rowtodelete = RowAgain
                        If rowtodelete > -1 Then
                            Listbox1.Items.RemoveAt(rowtodelete)
                            Listbox2.Items.RemoveAt(rowtodelete)
                        End If
                    End If
                Next
                If rowtodelete > -1 Then Exit For
            Next



    • Edited by Kevin993 Saturday, March 28, 2020 10:17 PM
    Saturday, March 28, 2020 10:14 PM
  • Hi

    Posts crossed in the ether ..............

    I altered the code I posted for multiple duplicates.


    Regards Les, Livingston, Scotland

    Saturday, March 28, 2020 10:19 PM
  • Hello,

    Here is an example that finds/removes the duplicate and then adds it to the second listbox via GroupBy in a lambda statement.

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim results = ListBox1.
                    Items.Cast(Of String).
                    Distinct().Select(Function(item) item).
                    ToArray()
    
            Dim diff = ListBox1.Items.Cast(Of String).
                    ToArray().
                    GroupBy(Function(x) x).
                    Select(Function(x) New With {Key .key = x.Key, Key .Count = x.Count()}).
                    Where(Function(x) x.Count > 1)
    
            ListBox1.Items.Clear()
            ListBox1.Items.AddRange(results)
    
            For Each item In diff
                ListBox2.Items.Add(item.key)
            Next
    
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    I tested your code,

    it works fine with deleting duplicates of Listbox1, but I'm not quite sure why it adds 123 to listbox2?

    Saturday, March 28, 2020 10:22 PM