c# - 比较元组,忽略元素的顺序

标签 c# .net comparison tuples c#-7.0

假设我有对象 Foo 和 Bar;和名为 A、B 和 C 的 3 个元组。

A = (Foo, Bar)
B = (Bar, Foo)
C = (Foo, Bar)

我想知道它们的元素是否相同,而不考虑元素的顺序。所以我想要的结果是;

A.HasSameElementsWith(B)  -> True
A.HasSameElementsWith(C)  -> True
B.HasSameElementsWith(C)  -> True

我知道我可以运行一个嵌套循环来比较它们的每个元素。类似的东西:

foreach (itemA in A)
{
    bool flag = false;

    foreach (itemB in B)
    {
        if(itemA == itemB)
        {
            flag = true;
            break;
        }
    }

    if (!flag) return false;
}

return true;

但这似乎效率低下。有没有更方便的方法来做到这一点?


注意:

我正在使用泛型,所以 FooBar 可以是任何类型。但它们彼此将是同一类型。 (即 Foo 的类型与 Bar 的类型相同)

最佳答案

如果您有两个二元组,那么根据您的规则只有两个选项可以让它们相等,您可以将其写成几乎是单行方法:

public static bool HasSameElementsWith<T>(this (T, T) tuple1, (T, T) tuple2) =>
    (Equals(tuple1.Item1, tuple2.Item1) && Equals(tuple1.Item2, tuple2.Item2)) ||
    (Equals(tuple1.Item1, tuple2.Item2) && Equals(tuple1.Item2, tuple2.Item1));

如果每个元组可以有两个以上的项目,那么我会开始将它们视为一个集合,然后问题就变成了两个集合是否具有相同的项目。为此,您可以计算 Dictionary<T, int> 中第一个集合中的每个项目。 ,然后倒数第二个集合中的项目。如果两个集合包含相同的项目,则最后所有计数都应为零。 (如果您确定每个集合中的项目都是唯一的,则可以改用 HashSet<T>。)在代码中:

public static bool HasSameElementsWith<T>(
    this IEnumerable<T> collection1, IEnumerable<T> collection2)
{
    var counts = new Dictionary<T, int>();

    foreach (var item in collection1)
    {
        counts.TryGetValue(item, out int count);
        count++;
        counts[item] = count;
    }

    foreach (var item in collection2)
    {
        counts.TryGetValue(item, out int count);
        if (count == 0)
            return false;
        count--;
        counts[item] = count;
    }

    return counts.Values.All(c => c == 0);
}

现在你可以实现 HasSameElementsWith 的元组版本了在收藏版之上:

public static bool HasSameElementsWith<T>(this (T, T) tuple1, (T, T) tuple2) =>
    HasSameElementsWith(tuple1.ToArray(), tuple2.ToArray());

public static T[] ToArray<T>(this (T, T) tuple) => new[] { tuple.Item1, tuple.Item2 };

关于c# - 比较元组,忽略元素的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44698041/

相关文章:

c# - 验证 .NET 时间格式的正则表达式

perl - 在 Perl 中检查字符串是否为空的正确方法是什么?

c - C中的直接调用与间接调用

c# - TFS API获取工作项数据

c# - 将一个方法作为参数传递给另一个方法

c# - 为什么在使用 read() 后从 c# 中的控制台为 readLine() 获取空值

c# - 将 ASP.NET Repeater 控件与 List<T> 对象数据一起使用

c# - 在序列中获取 "next"元素的最简单方法?

c# - 线程池为什么要这样管理线程呢?

java - 在java中将double与int进行比较是否有效?