Reputation: 185
Well, I need to check if there exists duplicate items inside listview on my app, but... I don't know how.
The way to detect this is by checking the field "Tag", if they are the same, then delete the item.
Upvotes: 2
Views: 10394
Reputation: 1
int J = 0;
In this simple code we will remove duplicates from a loop which will take the first item and compare it with the items bellow, so if it exists you can remove the above one or the second one
foreach (ListViewItem item1 in listView1.Items)
{
//J+1 to do not repeat the list from first and remove itself just take a look on next items
for (int i=J+1;i<listView1.Items.Count-1;i++)
{
//i compare two subitems that must be unique in my list
if (listView1.Items[J].SubItems[1].ToString() == listView1.Items[i].SubItems[1].ToString())
// listView1.Items.RemoveAt(i); // remove the second one
listView1.Items.RemoveAt(J); // remove the first one and keep the second
}
J++;
}
Upvotes: 0
Reputation: 484
None of the above helped me, so I thought I'd post what I came up with in case someone else is having this issue.
myListView is a ListView, sorted alphabetically (so duplicates in this case are adjacent). You could sort it programatically beforehand if you wanted.
myListView.Sorting = SortOrder.Ascending;
Anyway this is fairly simplistic but I hope it helps someone!
for (int i = 0; i < myListView.Items.Count - 1; i++)
{
if (myListView.Items[i].Tag == myListVIew.Items[i + 1].Tag)
{
myListView.Items[i + 1].Remove();
}
}
Upvotes: 2
Reputation: 1478
I would like to offer my solution using a Dictionary for future reference: (you will edit for your own "Colums" (subitems), Simply read the code to understand.
I used the below to remove "Dups" in a listview on a button click, i am searching subitem you can edit code for your own use...
uses dictionary and a little easy "update" class i wrote.
private void removeDupBtn_Click(object sender, EventArgs e)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
int num = 0;
while (num <= listView1.Items.Count)
{
if (num == listView1.Items.Count)
{
break;
}
if (dict.ContainsKey(listView1.Items[num].SubItems[1].Text).Equals(false))
{
dict.Add(listView1.Items[num].SubItems[1].Text, ListView1.Items[num].SubItems[0].Text);
}
num++;
}
updateList(dict, listView1);
}
and using a little updateList() class...
private void updateList(Dictionary<string, string> dict, ListView list)
{
#region Sort
list.Items.Clear();
string[] arrays = dict.Keys.ToArray();
int num = 0;
while (num <= dict.Count)
{
if (num == dict.Count)
{
break;
}
ListViewItem lvi;
ListViewItem.ListViewSubItem lvsi;
lvi = new ListViewItem();
lvi.Text = dict[arrays[num]].ToString();
lvi.ImageIndex = 0;
lvi.Tag = dict[arrays[num]].ToString();
lvsi = new ListViewItem.ListViewSubItem();
lvsi.Text = arrays[num];
lvi.SubItems.Add(lvsi);
list.Items.Add(lvi);
list.EndUpdate();
num++;
}
#endregion
}
Good luck!
Upvotes: 0
Reputation: 22759
If you are comparing duplicated Items based on specific columns you should simply use:
if(listview.Items.Find(SearchQuery).Count > 0)
{
//remove duplicates from list...
}
but you should name every item in the list when you fill up the listview.. for example if I want to search for duplicate items in column 1+2+5 I'd name the whole row like:
myItemName.Name = column1.Text + "_" + column2.Text + "_" + column5.Text;
and then perform the above "if statement"..
Upvotes: 0
Reputation: 19027
A good way to find duplicates is to use a temporary hashset. This gives you an O(n)
O(n log n)
algorithm (see Rick Sladkeys comments) to detect duplicates. Example:
var tags = new HashSet<string>();
var duplicates = new List<Item>();
foreach(Item item in listView.Items)
{
// HashSet.Add() returns false if it already contains the key.
if(!tags.Add(item.Tag)
duplicates.Add(item);
}
[Remove duplicates here]
Upvotes: 5
Reputation: 612934
If you have a lot of items then you can use a HashSet to keep the performance acceptable.
Loop over the items starting with the HashSet empty. For each item check if the tag is in the HashSet. If so this is a duplicate. If not add the tag to the HashSet.
This approach avoids an N^2 algorithm which is what you get with a nested loop. The HashSet makes the algorithm linear complexity providing the removal phase is carefully implemented. Of course this may not matter to you depending on how many items you have. If the list is small use nested loops and keep it simple.
Upvotes: 0
Reputation: 1083
Used nested for loops to go through and check each item against each other item.
//tag duplicates for removal
List<Item> toRemove = new List<Item>();
foreach(Item item1 in listView.Items)
{
foreach(Item item2 in listView.Items)
{
//compare the two items
if(item1.Tag == item2.Tag)
toRemove.Add(item2);
}
}
//remove duplicates
foreach(Item item in toRemove)
{
listView.Items.Remove(item);
}
You'll have to tweak the syntax for your code, but that's the basic idea behind it. Also, there are optimizations that could probably be made to it, but don't worry about those yet.
Upvotes: 2