How can I do simple order based validation on a collection of objects with LINQ?
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();
精彩评论