我想验证字符串在相邻位置是否包含任何重复字符(来自一组坏字符)。此主题的先前堆栈溢出答案似乎主要是一般形式:
for(int i = 0; i < testString.Length-1; i++){
if(testString[i] == testString[i+1] && testString[i] == badChar){
//Handle rejection here
}
}
是否可以在LINQ中进行此类验证/验证?更一般地说:在LINQ中是否可以将字符串中每个字符的值与
中的下一个字符进行比较 testString.Any(c => /*test goes here*/)
致电?
答案 0 :(得分:5)
您可以使用moreLINQ库中的Pairwise
:
if(testString.Pairwise((n, m) => new {n, m}).Any(x => x.n == x.m && x.n == badChar))
// do something
如果您想使用纯LINQ,可以使用Skip
/ Zip
组合破解它:
if(testString.Zip(testString.Skip(1), (n, m) => new {n, m})).Any(x => x.n == x.m && x.n == badChar))
// do something
但这两种解决方案都比for
基于循环的解决方案慢得多,所以我建议不要这样做。
答案 1 :(得分:4)
任何时候你有一个具有Count
(或等效)属性和索引器的类,你可以使用Enumerable.Range
作为LINQ查询的基础,并在类似于非LINQ代码的索引访问中执行:
bool test = Enumerable.Range(0, testString.Length - 1).Any(i = >
testString[i] == testString[i + 1] && testString[i] == badChar)
答案 2 :(得分:3)
如何严重滥用聚合函数?我想这个答案更像是一个不做的例子,即使它是可能的。一段时间和string.indexOf可能是最适合这个问题的。
var items = "ab^cdeef##gg";
var badChars = new[] {'^', '#', '~'};
var doesAdjacentDupeExist = false;
var meaninglessAggregate = items.Aggregate((last, current) =>
{
if (last == current && badChars.Contains(last))
{
doesAdjacentDupeExist = true;
};
return current;
});
这不是很聪明,但确实有效。它交换查询中的外部变量的设置(坏),依赖于index和elementAt(不是很好)。
var items = "abcdefffghhijjk";
var badChars = new[] { 'f', 'h' };
var indexCieling = items.Count() - 1;
var badCharIndexes = items.Select((item, index) =>
{
if (index >= indexCieling)
{
return null as int?;
}
else
{
if (item == items.ElementAt(index + 1) && badChars.Contains(item))
{
return index as int?;
}
else
{
return null as int?;
}
}
});
var doesAdjacentDupeExist = badCharIndexes.Any(x => x.HasValue);