5

在 C#/.NET 中肯定有一种简单的方法来验证值集合没有重复[使用's的默认Comparison值]?不必直接内置,但应该简短高效。collectionType

我已经看了很多,但我一直在寻找使用collection.Count() == collection.Distinct().Count()which 对我来说效率低下的例子。如果是这种情况,我对结果不感兴趣,并希望在检测到重复项后立即退出。

(如果有人可以指出重复项,我很想删除这个问题和/或其答案)

4

2 回答 2

9

好的,如果您只想在找到重复项后立即退出,这很简单:

// TODO: add an overload taking an IEqualityComparer<T>
public bool AllUnique<T>(this IEnumerable<T> source)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }
    var distinctItems = new HashSet<T>();
    foreach (var item in source)
    {
        if (!distinctItems.Add(item))
        {
            return false;
        }
    }
    return true;
}

...或使用All,正如您已经展示的那样。我认为在这种情况下这更容易理解......或者如果你确实想使用All,为了清楚起见,我至少将集合的创建与方法组转换分开:

public static bool IsUnique<T>(this IEnumerable<T> source)
{
    // TODO: validation
    var distinctItems = new HashSet<T>();
    // Add will return false if the element already exists. If
    // every element is actually added, then they must all be unique.
    return source.All(distinctItems.Add);
}
于 2013-07-18T11:27:59.597 回答
7

内联操作,您可以替换:

collection.Count() == collection.Distinct().Count()

collection.All( new HashSet<T>().Add );

T您的收藏元素的类型在哪里)

或者您可以将上述内容提取到辅助扩展方法 [1] 中,这样您就可以说:

collection.IsUnique()

[1]

static class EnumerableUniquenessExtensions
{
    public static bool IsUnique<T>(this IEnumerable<T> that)
    {
        return that.All( new HashSet<T>().Add );
    }
}

(正如乔恩在他的回答中指出的那样,一个人真的应该分开并评论这两行,因为这样的“可爱”通常不是一个好主意)

于 2013-07-18T11:20:37.620 回答