从多列列表视图中删除重复项 [英] Removing duplicate items from a multicolumn listview

查看:139
本文介绍了从多列列表视图中删除重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

回答过的问题

感谢您丹!您的code完美地工作,你今天救了我的命!许多网际网路给你的好先生。

Thank you Dan! Your code worked perfectly and you saved my life today! Many internets to you good sir.

我是慷慨的社会引导使用LINQ找到最后一次围绕在我的列表框重复。不过,我现在是在一个艰难的点,因为我需要找到和多列列表视图中删除重复。我试图使用LINQ,但它说,列表视图对象不是可查询。有没有办法对我来说,找到并删除使用列表视图的一列复制?

I was generously guided by the community to use LINQ to find duplicates on my listboxes the last time around. However, I am now in a tough spot because I need to find and remove duplicates from a multicolumn list view. I tried using LINQ but it says that the listview object is not "queryable". Is there a way for me to find and remove duplicates using only one column of the listview?

感谢

更新

Private Shared Sub RemoveDuplicateListViewItems(ByVal listView As ListView)
    Dim duplicates = listView.Items.Cast(Of ListViewItem)() _
    .GroupBy(Function(item) item.Text)
    .Where(Function(g) g.CountAtLeast(2))
    .SelectMany(Function(g) g)

    For Each duplicate As ListViewItem In duplicates
        listView.Items.RemoveByKey(duplicate.Name)
    Next
End Sub

这是我至今感谢丹。仍然得到了昏暗的重复线路故障。

This is what I have so far thanks to Dan. Still getting errors on the "Dim duplicates" line.

更新2 这里是code的模块和表单内的功能:

UPDATE 2 Here is the code for the Module and the Function inside the form:

Imports System.Runtime.CompilerServices

Module CountAtLeastExtension
    <Extension()> _
    Public Function CountAtLeast(Of T)(ByVal source As IEnumerable(Of T), ByVal minimumCount As Integer) As Boolean
        Dim count = 0
        For Each item In source
            count += 1
            If count >= minimumCount Then
                Return True
            End If
        Next

    Return False
End Function
End Module

    Private Shared Sub RemoveDuplicateListViewItems(ByVal listView As ListView)
    Dim duplicates = listView.Items.Cast(Of ListViewItem)() _
        .GroupBy(Function(item) item.Text) _
        .Where(Function(g) g.CountAtLeast(2)) _
        .SelectMany(Function(g) g)

    For Each duplicate As ListViewItem In duplicates
        listView.Items.RemoveByKey(duplicate.Name)
    Next
End Sub

在code现在,当我把它运行良好。但它不会删除重复的:

The code now runs fine when I call it. But it does not remove the duplicates:

重复的例子

也许这个截图中,你可以看到我打算在这里。非常感谢你这么耐心跟我来!

Maybe with this screenshot you can see what I am going for here. Thank you very much for being so patient with me!

推荐答案

那么,你需要一些方法来确定两个的ListViewItem 对象是否是重复的。

Well, you'll need some method for determining whether two ListViewItem objects are duplicates.

一旦在地方的,实施是相当简单的。

Once that's in place, the implementation is fairly straightforward.

比方说,你要考虑的两个项目是相同的,如果在第一列中的文本是相同的(例如)。然后,你可以写了快的IEqualityComparer&LT; ListViewItem的&GT; 的实施,如:

Let's say you want to consider two items to be the same if the text in the first column is the same (for example). Then you might write up a quick IEqualityComparer<ListViewItem> implementation such as:

class ListViewItemComparer : IEqualityComparer<ListViewItem>
{
    public bool Equals(ListViewItem x, ListViewItem y)
    {
        return x.Text == y.Text;
    }

    public int GetHashCode(ListViewItem obj)
    {
        return obj.Text.GetHashCode();
    }
}

然后,你可以删除重复像这样:

Then you could remove duplicates like so:

static void RemoveDuplicateListViewItems(ListView listView)
{
    var uniqueItems = new HashSet<ListViewItem>(new ListViewItemComparer());

    for (int i = listView.Count - 1; i >= 0; --i)
    {
        // An item will only be added to the HashSet<ListViewItem> if an equivalent
        // item is not already contained within. So a return value of false indicates
        // a duplicate.
        if (!uniqueItems.Add(listView.Items[i]))
        {
            listView.Items.RemoveAt(i);
        }
    }
}


更新:以上code消除了出现在的ListView 详细的任何物品的重复的超过一次;也就是说,它留下的每一个实例。如果你想要的行为实际上是删除所有中出现不止一次的任何项目情况下,这种方法是有点不同的。


UPDATE: The above code removes the duplicates of any items that appear in the ListView more than once; that is, it leaves one instance of each. If the behavior you want is actually to remove all instances of any items that appear more than once, the approach is a little bit different.

下面是你可以做这件事。首先,定义如下扩展方法:

Here's one way you could do it. First, define the following extension method:

public static bool CountAtLeast<T>(this IEnumerable<T> source, int minimumCount)
{
    int count = 0;
    foreach (T item in source)
    {
        if ((++count) >= minimumCount)
        {
            return true;
        }
    }

    return false;
}

然后,找到像这样重复的:

Then, find duplicates like so:

static void RemoveDuplicateListViewItems(ListView listView)
{
    var duplicates = listView.Items.Cast<ListViewItem>()
        .GroupBy(item => item.Text)
        .Where(g => g.CountAtLeast(2))
        .SelectMany(g => g);

    foreach (ListViewItem duplicate in duplicates)
    {
        listView.Items.RemoveByKey(duplicate.Name);
    }
}


更新2 :这听起来像你已经能够转换最上面到VB.NET了。这是给你的麻烦就行可以写成如下:


UPDATE 2: It sounds like you've been able to convert most of the above to VB.NET already. The line that is giving you trouble can be written as follows:

' Make sure you have Option Infer On. '
Dim duplicates = listView.Items.Cast(Of ListViewItem)() _
    .GroupBy(Function(item) item.Text) _
    .Where(Function(g) g.CountAtLeast(2)) _
    .SelectMany(Function(g) g)

另外,如果你有使用 CountAtLeast 方法,用上述方法有任何问题,你需要使用<一个href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.extensionattribute.aspx"相对=nofollow> ExtensionAttribute 类写扩展方法在VB.NET:

Also, in case you have any trouble using the CountAtLeast method in the above way, you need to use the ExtensionAttribute class to write extension methods in VB.NET:

Module CountAtLeastExtension

    <Extension()> _
    Public Function CountAtLeast(Of T)(ByVal source As IEnumerable(Of T), ByVal minimumCount As Integer) As Boolean
        Dim count  = 0
        For Each item in source
            count += 1
            If count >= minimumCount Then
                Return True
            End If
        Next

        Return False
    End Function

End Module

这篇关于从多列列表视图中删除重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆