我写了一个非常基本的update
语句来获取数组中所有重复字母的字符串。这样做的代码很简单,但是我可以看到,对于团队中一些经验不足的开发人员(或不熟悉Linq
的开发人员)来说,维护起来很困难。
Linq
我总是可以将其分解为嵌套的string[] results = values.Where(v => v.Where(w => v.Count(c => c == w) > 1).Any()).ToArray();
Console.WriteLine($"There are {results.Length} items with duplicate letters: {string.Join(", ", results)}");
循环,或以其他几种方式编写:
foreach
但是,我一直想了解有关实际 List<string> results = new List<string>();
foreach (string v in values) {
List<char> chars = new List<char>();
foreach (char c in v.ToUpperInvariant()) {
if (chars.Contains(c)) {
results.Add(v);
break;
}
chars.Add(c);
}
}
Console.WriteLine($"There are {results.Count} items with duplicate letters: {string.Join(", ", results.ToArray())}");
查询的更多信息,因为它们似乎比内联Linq
更具可读性。我更喜欢像在Linq
查询中经常看到的那样命名变量:
Linq
我认为,与大多数List<string> myStrings = from val in values ...
代码一样,在保持简洁性的同时,它将更易于维护,但是我无法以嵌套的方式围绕查询查询。我一直尝试将其写为:
Linq
但是我相信它可能更像是:
string[] results = from val in values
where from currentCharacter in val
where ...
老实说,我也不认为这是实现此目的的正确方法,但这就是为什么我在这里。
如何将嵌套的string[] results = from val in values
join currentCharacter in val on ...
语句从内联转换为查询?
答案 0 :(得分:3)
您可以转换流利的语法代码:
values.Where(v => v.Where(w => v.Count(c => c == w) > 1).Any()).ToArray();
通过查询语法+流利的语法:
var result = (from val in values
where val.Any(w => val.Count(c => c == w) > 1)
select val).ToArray();
如您所见,这仍然涉及方法调用,这仅仅是因为某些查询必须表示为方法调用,因为Any
和Count
没有查询表达式语法(据我所知)。
基本上以一种或另一种方式,您最终将需要在管道中的某处涉及方法调用。
您可能想做的另一件事是将where
逻辑提取到某种方法中,例如
bool HasDuplicateCharacters(string input) => input.Any(w => input.Count(c => c == w) > 1);
然后查询将变为:
var result = (from val in values
where HasDuplicateCharacters(val)
select val).ToArray();
与上面的“完全”流利的语法相比,现在阅读此书的任何人都应该知道代码在做什么。
答案 1 :(得分:2)
使用LINQ的好处之一是它专注于意图,不会使读者陷入困境。这对维护很重要:您越早了解它的作用,就越早知道如何进行所需的更改。
使用LINQ语法(from ...
)而非流利的(扩展方法)语法也可能有所帮助。例如,在我的答案here中,LINQ语法使查询更易于理解。不管哪种方法都可以。
对于转换嵌套查询,我建议向外进行,因此从内部查询开始,然后首先进行转换。
v.Where(w => v.Count(c => c == w) > 1).Any()
成为:
(from w in v
where v.Count(c => c == w) > 1
select w).Any()
然后使用in作为您的外部查询的谓词:
string[] results = (from v in values
where (from w in v
where v.Count(c => c == w) > 1
select w
).Any()
select v
).ToArray();
完成该练习后,它看起来仍然有些毛茸茸。其他人建议做一个内部方法,我不会不同意。尽管如此,还是知道如何进行翻译还是很不错的,不仅可以在这种情况下做出充分知情的决定,而且将来也可以对其他查询做出决定。
关于团队的经验,这是一个在学习LINQ的同时向其他人教授LINQ的绝好机会。使用代码审查或午餐非学习课程来讨论技术并互相学习。 “教书是学习两次。”
最后,谈到技术时,“ LINQ”是正确的大小写,而.NET命名约定对众所周知的首字母缩略词使用大小写混合,因此“ Linq”用于诸如名称空间之类的标识符中。 System.Linq
。