如何创建一个HashSet<List<Int>>具有不同的元素? [英] How to create a HashSet&lt;List&lt;Int&gt;&gt; with distinct elements?

查看:19
本文介绍了如何创建一个HashSet<List<Int>>具有不同的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个整数列表的 HashSet - 即 HashSet>

I have a HashSet that contains multiple lists of integers - i.e. HashSet<List<int>>

为了保持独特性,我目前必须做两件事:1. 手动循环遍历现有列表,使用 SequenceEquals 查找重复项.2. 对各个列表进行排序,以便 SequenceEquals 当前有效.

In order to maintain uniqueness I am currently having to do two things: 1. Manually loop though existing lists, looking for duplicates using SequenceEquals. 2. Sorting the individual lists so that SequenceEquals works currently.

有没有更好的方法来做到这一点?是否有现有的 IEqualityComparer 可以提供给 HashSet,以便 HashSet.Add() 可以自动处理唯一性?

Is there a better way to do this? Is there an existing IEqualityComparer that I can provide to the HashSet so that HashSet.Add() can automatically handle uniqueness?

var hashSet = new HashSet<List<int>>();

for(/* some condition */)
{
    List<int> list = new List<int>();

    ...

    /* for eliminating duplicate lists */

    list.Sort();

    foreach(var set in hashSet)
    {
        if (list.SequenceEqual(set))
        {
            validPartition = false;
            break;
        }
    }

    if (validPartition)
           newHashSet.Add(list);
}

推荐答案

这里是一个可能的比较器,它比较 IEnumerable 的元素.添加前仍需手动排序.

Here is a possible comparer that compares an IEnumerable<T> by its elements. You still need to sort manually before adding.

可以将排序构建到比较器中,但我认为这不是明智的选择.添加列表的规范形式似乎更明智.

One could build the sorting into the comparer, but I don't think that's a wise choice. Adding a canonical form of the list seems wiser.

此代码仅适用于 .net 4,因为它利用了通用差异.如果您需要更早的版本,您需要将 IEnumerable 替换为 List,或者为集合类型添加第二个泛型参数.

This code will only work in .net 4 since it takes advantage of generic variance. If you need earlier versions you need to either replace IEnumerable with List, or add a second generic parameter for the collection type.

class SequenceComparer<T>:IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> seq1,IEnumerable<T> seq2)
    {
        return seq1.SequenceEqual(seq2);
    }

    public int GetHashCode(IEnumerable<T> seq)
    {
        int hash=1234567;
        foreach(T elem in seq)
            hash=hash*37+elem.GetHashCode();
        return hash;
    }
}

void Main()
{
    var hashSet = new HashSet<List<int>>(new SequenceComparer<int>());

    List<int> test=new int[]{1,3,2}.ToList();
    test.Sort();
    hashSet.Add(test);

    List<int> test2=new int[]{3,2,1}.ToList();
    test2.Sort();       
    hashSet.Contains(test2).Dump();
}

这篇关于如何创建一个HashSet<List<Int>>具有不同的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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