0

I'm trying to make a listbox where i can add items to it using datagridview, the thing is i want to determine which item is duplicate and how many times it duplicate.

  • item1
  • item1
  • item2
  • item2
  • item2

output item1=2, item2=3


Here is the one that i tried which shows the last item that have been duplicate

int count = 0;

 for (int i = 0; i < listBox1.Items.Count; i++)
 {
  var s = listBox1.Items[i].ToString();
  if (s.StartsWith(listfood))
   {
    if (s == listfood)
     {
      ++count;
     }             
   }
 }
MessageBox.Show(count.ToString());
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
krljde
  • 1
  • 3

3 Answers3

3

Try

var duplicateItems = listBox1.Items.GroupBy(x => x.ToString())
            .Where(x => x.Count() > 1)
            .Select(x => new { Value = x.Key, Count = x.Count() })
            .ToList();
Matt.G
  • 3,586
  • 2
  • 10
  • 23
2
using System.Linq;

// ...

var duplicates = listBox1.Items.GroupBy(x => x)
                               .Where(g => g.Count() > 1)
                               .Select(y => new { ItemName = y.Key, Occurrences = y.Count() })
                               .ToList();

foreach (var duplicate in duplicates)
    MessageBox.Show($"{duplicate.ItemName}: {duplicate.Occurrences}");

This solution uses LINQ to query the listBox1's Items collection and filter out any data we don't care about.

First, we use GroupBy to sort the items. Then, Where will filter out any items in the collection that only exist once. Select allows us to "project" the items remaining in the filtered collection into a "new form" (we use an anonymous type with an ItemName and Occurrences property to track the names of the duplicates and the number of times it appears in the collection).

Finally, ToList converts the collection from an IEnumerable<string> to aListtype.ToListis optional depending on how you plan on usingduplicates. In fact, my example doesn't need to callToListbecause aforeachloop can iterate over anIEnumerable` collection.

Lews Therin
  • 3,707
  • 2
  • 27
  • 53
  • I can't understand how to make this work I'm pretty new to c# and i'm using this to output on a Form in visual studio. Can you explain how your code works? – krljde Mar 28 '19 at 04:04
  • @krljde Sorry, I quickly wrote that and had it write the output to the Console. I edited my answer so now it does a message box like your original example. I'll also add a short explanation. – Lews Therin Mar 28 '19 at 22:08
0

I know the Answers above will definitely work, but i can't understand it and make it work. This one works for me, where i transfer values of listbox to an array and check the duplicates inside that array.

     var list = new List<string>();
            foreach(var item in listBox1.Items)
            {
                list.Add(item.ToString());
            }
            var r = from b in list
                    group b by b into g
                    let count = g.Count()
                    orderby count descending
                    select new { Value = g.Key, Count = count };
            foreach(var x in q)
            {
                MessageBox.Show("value: " + b.Value + " Count:" + b.Count);
            }

Found my answer here

krljde
  • 1
  • 3
  • Linq Query Expressions is used in this answer, where as Linq Fluent Expressions is used in the other answers. [Ref](https://stackoverflow.com/questions/214500/fluent-and-query-expression-is-there-any-benefits-of-one-over-other). you could still avoid using the list variable and the for loop by simply changing the code to var r = from b in listBox1.Items.Select(x => x.ToString()) – Matt.G Mar 28 '19 at 10:55