【问题标题】:Check if all values are equal in a list检查列表中的所有值是否相等
【发布时间】:2012-11-11 22:54:22
【问题描述】:
Class order {
Guid Id;
int qty;
}

使用 LINQ 表达式,我如何验证 qty 对于列表中的所有订单是否相同?

提前致谢!

【问题讨论】:

    标签: c# linq lambda


    【解决方案1】:

    你可以使用GroupBy:

    bool allEqual = orders.GroupBy(o => o.qty).Count() == 1;
    

    或者,效率更高但可读性更低:

    bool allEqual = !orders.GroupBy(o => o.qty).Skip(1).Any();
    

    或者,使用Enumerable.All 肯定更有效:

    int firstQty = orders.First().qty;  // fyi: throws an exception on an empty sequence
    bool allEqual = orders.All(o => o.qty == firstQty); 
    

    【讨论】:

    • 如果你在 lambda 中移动 orders.First().qty,你不会得到空序列的异常(因为如果序列为空,则不会调用 lambda) - 以重新计算为代价每次调用 lambda 时的值。
    • @sepp2k:因此我会简单地在开头使用if(orders.Any()){}。这既清晰又高效。
    • 你可以通过var allEqual = !orders.GroupBy(o => o.qty).Skip(1).Any()稍微提高GroupBy版本的效率。现在,如果您有很多数量,它只会检查是否存在第二个而不是计算所有组(但是 .All( 版本仍然更好)。
    【解决方案2】:

    如果只是为了提高可读性,我会添加一个扩展方法。

    public static bool AllEqual<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer = null)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));
    
        comparer = comparer ?? EqualityComparer<T>.Default;
    
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                var value = enumerator.Current;
    
                while (enumerator.MoveNext())
                {
                    if (!comparer.Equals(enumerator.Current, value))
                        return false;
                }
            }
    
            return true;
        }
    }
    

    调用它:

    var qtyEqual = orders.Select(order => order.qty).AllEqual();
    

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 2013-01-27
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 2022-01-07
      相关资源
      最近更新 更多