如何使用LINQ对一组对象进行简单的基于订单的验证?

时间:2010-12-09 03:52:53

标签: c# linq

给定单个对象集合,我想确定某些对象是否仅出现在另一个对象之后。

例如说我有一个字符串列表,如

A B B b b a a C c

我想检查每个小写字母是否至少有一个大写字母出现在序列之前。因此,上述序列将是无效的,因为有两个小写字母'a'和只有一个'A')。但以下内容是有效的:

A a B b

A B a b

A B b a

B A a b

...

有没有办法用LINQ做到这一点?

3 个答案:

答案 0 :(得分:2)

我认为您的意思是IEnumerable<char>而不是IEnumerable<string>

使用 Rollup 扩展方法[{3}}(“SelectAggregate扩展方法之间的交叉”),你可以做:

IEnumerable<char> chars = ...

bool isValid = chars.Where(char.IsLetter)
                    .GroupBy(char.ToUpperInvariant)
                    .SelectMany(g => g.Rollup(0, 
                                (c, sum) => sum + (char.IsUpper(c) ? 1 : -1)))
                    .All(runningTotal => runningTotal >= 0);

为完整起见,该方法的代码如下:

public static IEnumerable<TResult> Rollup<TSource, TResult>(
    this IEnumerable<TSource> source,
    TResult seed,
    Func<TSource, TResult, TResult> projection)
{
    TResult nextSeed = seed;
    foreach (TSource src in source)
    {
        TResult projectedValue = projection(src, nextSeed);
        nextSeed = projectedValue;
        yield return projectedValue;
    }
}

答案 1 :(得分:2)

这很容易:

bool isValid = !source.Where(char.IsLetter)
                     .Where((ch, index) =>
                         {
                            var temp = source.Take(index+1);
                            return temp.Count(c => c == char.ToUpper(c)) 
                                   < temp.Count(c => c == char.ToLower(c));
                         })
                     .Any();

答案 2 :(得分:1)

尝试这个

List<string> lstString = new List<string>();
        lstString.Add("A");
        lstString.Add("a");
        lstString.Add("A");
        lstString.Add("a");
        lstString.Add("B");
        lstString.Add("b");
        lstString.Add("B");
        lstString.Add("b");
        lstString.Add("C");
        lstString.Add("c");
        lstString.Add("C");
        lstString.Add("c");

        List<string> uniqueList = (from lst in lstString select lst).Distinct().ToList();