首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HashSet of Guid与Tuple<Guid,Guid> as Dictionary : Guid的顺序不重要

HashSet of Guid与Tuple<Guid,Guid> as Dictionary : Guid的顺序不重要
EN

Stack Overflow用户
提问于 2021-08-24 07:59:40
回答 2查看 363关注 0票数 0

我需要字典,它的键需要两个guid顺序的guid不重要。我有两个解决方案,在下面提到,我想知道哪一个更好,我应该去哪一个,如果在未来我需要添加第3 guid以及部分键。表现固然重要,但如果差别不大,那就没问题了。

第一解

代码语言:javascript
复制
 var guids = guids
     .OrderBy(g => g.ToString("N")) // Ordering so key always come as sorted 
     .ToList();

dict[Tuple.Create(guids[0], guids[1]) = "RandomObj";

第二解

代码语言:javascript
复制
public class GuidsModel
    {
        public GuidsModel(Guid guid1, Guid guid2)
        {
            Guid1= guid1;
            Guid2= guid2;
        }

        public Guid Guid1 { get; private set; }

        public Guid Guid2 { get; private set; }
    }

 public class GuidsModelComparer : IEqualityComparer<GuidsModel>
    {
        public static GuidsModelComparer Default = new GuidsModelComparer();

        private static IEqualityComparer<HashSet<Guid>> _hashSetComparer = HashSet<Guid>.CreateSetComparer();

        public bool Equals(GuidsModel x, GuidsModel y)
        {
            return _hashSetComparer.Equals(new HashSet<Guid> { x.Guid1, x.Guid2}, new HashSet<Guid> { y.Guid1, y.Guid2});
        }

        public int GetHashCode(GuidsModel obj)
        {
            if (obj == null)
                return 0;

            return _hashSetComparer.GetHashCode(new HashSet<Guid> { obj.Guid1, obj.Guid2});
        }

// usage
var dict = new Dictionary<GuidsModel, object>(GuidsModelComparer.Default);
dict[new GuidsModel(guids[0], guids[1])] = "RandomObj";
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-24 08:34:49

它在很大程度上取决于上下文,但我想说,如果您想在多个地方访问字典,将guid“排序”逻辑封装在一个地方就更有意义了。而且,就我个人而言,我只是在模型本身中实现EqualsGetHashcode,而不是创建自定义比较器。

代码语言:javascript
复制
public class GuidsModel
{
    public GuidsModel(Guid guid1, Guid guid2)
    {
        if (guid1.CompareTo(guid2) > 0) // when there will be more than 2 guids can switch to ordering collection i.e. new [] {guid1, guid2, guid3}.OrderBy()...
        {
            Guid1 = guid1;
            Guid2 = guid2;
        }
        else
        {
            Guid1 = guid2;
            Guid2 = guid1;
        }
    }

    public Guid Guid1 { get; private set; }
    public Guid Guid2 { get; private set; }

    private bool Equals(GuidsModel other)
    {
        return Guid1.Equals(other.Guid1) && Guid2.Equals(other.Guid2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((GuidsModel)obj);
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Guid1, Guid2);
    }
}

小提琴

票数 1
EN

Stack Overflow用户

发布于 2021-08-24 10:55:49

据我所知,您需要一个HashSet<Something>,这个东西包含两个相同类型的值,如果顺序不同,HashSet也应该匹配。

得到这个忽略的顺序是相当复杂的。但是,如果您使用一个工厂方法来创建实例,并且这个工厂方法负责排序,那么它就变得简单得多:

代码语言:javascript
复制
// Some class that holds two Guids, but it respects ordering
public record GuidPair(Guid First, Guid Second);

public static class Create
{
    public static GuidPair GuidPair(Guid first, Guid second)
    {
        // Order guids somehow in factory method to ensure
        // correct equality comparison
        if (first.CompareTo(second) > 0)
            return new GuidPair(second, first);
        else
            return new GuidPair(first, second);
    }
}

public static class Program
{
    public static void Main(string[] args)
    {
        // Some source for Guid values.
        var values = Enumerable.Range(0, 100)
            .Select(_ => Guid.NewGuid());

        // Create a HashSet with arbitrary values.
        var hashes = values.Zip(values)
            .Select(pair => Create.GuidPair(pair.First, pair.Second))
            .ToHashSet();

        // Pick some "random" element
        var someEntry = hashes.Skip(17).First();
        // Create explicitly a new item with values swapped (with factory method).
        var toCompare = Create.GuidPair(someEntry.Second, someEntry.First);

        // Check if default HashSet comparer works.
        var isAvailable = hashes.Contains(toCompare);

        // Prints "Found { first = Guid, second = Guid }: true"
        Console.WriteLine($"Found {toCompare}: {isAvailable}");

        Console.ReadKey();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68903816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档