开发者

When searching for an item in a generic list should I use LINQ or Contains?

I have a generic List and I have to find a particular string in this list. Could you please let me know which is the best approach in the below?

if (strlist.开发者_如何学CContains("Test"))
{
    // String found
}

or

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

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

Please consider the list may be very big populated from database. Your thoughts on this are highly appreciated.


If you have List<string> (or even IEnumerable<string>) and Contains meets your needs, then use Contains.

If you need some extra handling that Contains doesn't provide, I would suggest using Any():

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


The two methods will behave differently if there is more than one match; the first one will return true and the second one will throw an exception.

To correct that, change SingleOrDefault to FirstOrDefault.

To answer the question, you should call Contains if you're searching for an exact match and Any if you aren't.

For example:

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

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


You really should use HashSet<string> as the the performance of Contains is dramatically better. Now if you need to use a list for other operations you can simply have both available.

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

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

Now you have the ability to find items in the set as a O(1) operation.

Test

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();
    }
}

Result

0.308438 s
0.0197868 s
0.0 s

So what does this tell us? If you are making a small amount of calls to Contains use a List<string>, otherwise use a HashSet<string>.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜