在通用列表中搜索项目时,我应该使用LINQ还是包含?

时间:2010-07-28 15:45:11

标签: c# .net linq search

我有一个通用的List,我必须在此列表中找到一个特定的字符串。能告诉我下面哪种方法最好吗?

if (strlist.Contains("Test"))
{
    // String found
}

string res = (from d in strlist where d == "Test" select d).SingleOrDefault();

if (res == "Test")
{
    //found
}

请考虑从数据库填充的列表可能非常大。您对此的看法非常感谢。

3 个答案:

答案 0 :(得分:5)

如果您有List<string>(或甚至IEnumerable<string>)并且包含符合您的需求,请使用包含。

如果你需要一些Contains没有提供的额外处理,我建议使用Any():

if(strList.Any(s => s.StartsWith("Tes"))
{
    // Found
}

答案 1 :(得分:2)

如果有多个匹配,这两种方法的行为会有所不同;第一个将返回true,第二个将抛出异常。

要更正此问题,请将SingleOrDefault更改为FirstOrDefault

要回答这个问题,如果您正在搜索完全匹配,则应致电Contains,如果不是,则应致电Any

例如:

if (strings.Contains("SomeString", StringComparer.OrdinalIgnoreCase))

if (strings.Any(s => s.StartsWith("b"))

答案 2 :(得分:0)

你真的应该使用HashSet<string>,因为Contains的表现要好得多。现在,如果您需要使用列表进行其他操作,您可以同时使用它们。

var list = BuildListOfStrings();
var set = new HashSet<string>(list);

if (set.Contains("Test"))
{
    // ...
}

现在,您可以在集合中查找O(1)操作中的项目。

<强>测试

static void Main(string[] args)
{
    var lst = GenerateStrings().Take(5000000).ToList();
    var hsh = new HashSet<string>(lst);
    var found = false;
    var count = 100;
    var sw = Stopwatch.StartNew();

    for (int i = 0; i < count; i++)
    {
        hsh = new HashSet<string>(lst);
    }
    Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));

    sw = Stopwatch.StartNew();
    for (int i = 0; i < count; i++)
    {
        found = lst.Contains("12345678");
    }
    Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));

    sw = Stopwatch.StartNew();
    for (int i = 0; i < count; i++)
    {
        found = hsh.Contains("12345678");
    }
    Console.WriteLine(TimeSpan.FromTicks(sw.ElapsedTicks / count));

    Console.WriteLine(found);
    Console.ReadLine();
}

private static IEnumerable<string> GenerateStrings()
{
    var rnd = new Random();
    while (true)
    {
        yield return rnd.Next().ToString();
    }
}

<强>结果

0.308438 s
0.0197868 s
0.0 s

那么这告诉我们什么?如果您拨打少量电话Contains,请使用List<string>,否则请使用HashSet<string>