开发者

How can I do simple order based validation on a collection of objects with LINQ?

开发者 https://www.devze.com 2023-01-29 08:43 出处:网络
Given a single collection of objects I want to determine if certain object开发者_运维问答s only appear after another object.

Given a single collection of objects I want to determine if certain object开发者_运维问答s only appear after another object.

For example say I had a list of strings such as

A B B b b a a C c

I'd want to check if for every lower case letter there is at least as many upper case letters that appears before it in the sequence. Thus the above sequence would be invalid since there are two lower case 'a' and only one 'A'). But the following would be valid:

A a B b

A B a b

A B b a

B A a b

...

Is there way to do that using LINQ?


I think you mean an IEnumerable<char> rather than an IEnumerable<string>?

Using the Rollup extension-method described here ("a cross between the Select and Aggregate extension methods"), you could do:

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);

For completeness, the code for that method is given as:

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;
    }
}


It can be very easy:

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();


Try this one too

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();
0

精彩评论

暂无评论...
验证码 换一张
取 消