Linq way of checking that no items in a collection match any other item
我取一个线段集合,修剪任何重叠的部分,我应该得到一个不作为输出重叠的集合。
为了测试我的输出,我希望迭代集合中的每个项,并确保它不与任何其他项重叠。
目前我有以下代码:
1 2 3 4 5 6 7 | foreach (var assay in compiledAssays) { if (compiledAssays.Where(a => a != assay).Any(a => a.Overlaps(assay))) { throw new ApplicationException("Something went wrong."); } } |
它可读,但对我来说"闻起来很难闻"。似乎它至少要在集合中迭代三次才能进行测试。
有没有更好的方法来表达这个测试?
合并
1 2 3 4 5 6 7 | foreach (var assay in compiledAssays) { if (compiledAssays.Any(a => a != assay && a.Overlaps(assay))) { throw new ApplicationException("Something went wrong."); } } |
你也可以试着更简洁些:
1 2 3 4 | if (compiledAssays.Any(a => compiledAssays.Any(b => a != b && a.Overlaps(b)))) { throw new ApplicationException("Something went wrong.""); } |
否则,如果您主要关心的是最小化执行的循环的数量,那么我不会使用LINQ。我会这样做(假设
1 2 3 4 5 6 7 8 9 10 | for (int i = 0; i < compiledAssays.Length; i++) { for (int j = i + 1; j < compiledAssays.Length; j++) { if (compiledAssays[i].Overlaps(compiledAssays[j])) { throw new ApplicationException("Something went wrong."); } } } |
编辑:陈雷蒙的一个非常中肯的评论。
最后一个选项假设
换句话说,
您的第一个
1 2 3 4 5 6 7 8 9 10 11 | for (int i = 0; i < compiledAssays.Length; i++) { for (int j = i + 1; j < compiledAssays.Length; j++) { if (compiledAssays[i] != compiledAssays[j] && compiledAssays[i].Overlaps(compiledAssays[j])) { throw new ApplicationException("Something went wrong."); } } } |
为了复制操作,再次假设