代码之家  ›  专栏  ›  技术社区  ›  Coxy

检查集合中没有项目与任何其他项目匹配的Linq方法

  •  3
  • Coxy  · 技术社区  · 9 年前

    我正在收集一组线段并修剪任何重叠的线段,我应该得到一个不重叠的线段作为输出。

    为了测试我的输出,我希望遍历集合中的每个项,并确保它不与任何其他项重叠。

    目前我有此代码:

    foreach (var assay in compiledAssays)
    {
        if (compiledAssays.Where(a => a != assay).Any(a => a.Overlaps(assay)))
        {
            throw new ApplicationException("Something went wrong.");
        }
    }
    

    它是可读的,但对我来说“闻起来很难闻”。看起来它至少要在集合中迭代三次才能进行测试。

    有更好的方法来表达这个测试吗?

    2 回复  |  直到 9 年前
        1
  •  3
  •   sstan    9 年前

    嗯,合并 Where 以及 Any 条款将是第一个很好的改进:

    foreach (var assay in compiledAssays)
    {
        if (compiledAssays.Any(a => a != assay && a.Overlaps(assay)))
        {
            throw new ApplicationException("Something went wrong.");
        }
    }
    

    您也可以尝试更简洁的方法:

    if (compiledAssays.Any(a => compiledAssays.Any(b => a != b && a.Overlaps(b))))
    {
        throw new ApplicationException("Something went wrong."");
    }
    

    否则,如果您主要关注的是最小化执行的循环数量,我就不会使用Linq。我会这样做(假设 compiledAssays 是数组,根据需要进行调整):

    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.");
            }
        }
    }
    

    编辑: Raymond Chen的一个非常中肯的评论。

    我的最后一个选项假设 Overlaps 函数是对称的。

    换句话说 a.Overlaps(b) 将始终返回与 b.Overlaps(a) 。如果不是这样,那么我的最后一个选项是错误的。

        2
  •  1
  •   Mark Hurd    9 年前

    你的第一个 Where 子句排除完全重复项(取决于 != 定义为用于 assay ),因此您可以使用 compiledAssays.Distinct 作为基本枚举,但如果您可以使用排序来优化重叠搜索,但以额外循环为代价,现在接受的答案的显式双循环是好的,除非它当前不排除所有重复。应该是:

    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.");
            }
        }
    }
    

    复制OP,再次假设 Overlaps 是对称的。