使用linq查找不在现有列表中的下一个增量值

时间:2013-10-30 09:24:54

标签: c# linq

我在IntExtensions类中有两个方法来帮助生成下一个可用的增量值(不在需要排除的现有整数列表中)。 我不认为我正在以最好的方式解决NextIncrementalValueNotInList方法,我想知道我是否可以更好地使用linq来返回下一个可用的int?

public static bool IsInList(this int value, List<int> ListOfIntegers) {
    if (ListOfIntegers.Contains(value))
        return true;

    return false;
}

public static int NextIncrementalValueNotInList(this int value, 
                                                List<int> ListOfIntegers) {

        int maxResult;
        maxResult = ListOfIntegers.Max() + 1;

        for (int i = value; i <= maxResult; i++)
        {
            if (!(i.IsInList(ListOfIntegers)))
            {
                return i;
            }
        }
        return maxResult;
    }

3 个答案:

答案 0 :(得分:5)

使用linq,您的方法将如下所示:

return IEnumerable.Range(1, ListOfIntegers.Count + 1)
                  .Except(ListOfIntegers)
                  .First();

答案 1 :(得分:2)

我猜它从1开始。

您也可以这样继续:

IEnumerable.Range(1, ListOfIntegers.Count)
           .Where(i => !ListOfIntegers.Contains(i))
           .Union(new []{ ListOfIntegers.Count + 1 })
           .First();

答案 2 :(得分:2)

您实际上不需要计算Max值 - 只需保持递增i,直到找到列表中不存在的值,例如:

public static int NextIncrementalValueNotInList(this int value, 
  List<int> ListOfIntegers)
{
    int i = value;

    while(true)
    {
        if (!(i.IsInList(ListOfIntegers)))
        {
            return i;
        }
        i++;
    }
    return maxResult;
}

。除此之外,我不确定你能做些什么,除非:

  • ListOfIntegers保证是或者需要排序,或
  • ListOfIntegers实际上不一定是List<int>

如果对第一个的答案是否定,而对第二个答案是肯定的,那么您可以使用HashSet<int>可能通过允许您简单地使用来提供更快的实施HashSet<T>自己的bool Contains(T)方法:

public static int NextIncrementalValueNotInList(this int value, 
  HashSet<int> ListOfIntegers) 
{
    int i = value;
    while(true)
    {
        if (!(ListOfIntegers.Contains(i))
        {
            return value;
        }
        i++;
    }
}

请注意,此版本还显示了如何取消Max检查。

虽然要小心过早优化 - 如果你当前的实施足够快,那我就不用担心了。您应该针对极端情况以及真实案例正确地对任何替代解决方案进行基准测试,以确定是否存在任何差异。

另外,您不想做的就是使用我的建议,将每个电话的列表变为HashSet。我建议完全改变您对ListHashSet的使用情况 - 由于创建HashSet的费用,任何可能的逐个转化都会抵消任何潜在的性能优势。

最后,如果您实际上并未期望整数列表中存在太多碎片,那么HashSet可能与当前的Linq版本没有太大区别,因为它可能最终会做类似的数量无论如何都要工作。