在LINQ中找到List中的项目?

Dav*_*.ca 213 c# linq

这里我有一个简单的例子来查找字符串列表中的项目.通常我使用for循环或匿名委托来这样做:

int GetItemIndex(string search)
{
   int found = -1;
   if ( _list != null )
   {
     foreach (string item in _list) // _list is an instance of List<string>
     { 
        found++;
        if ( string.Equals(search, item) )
        {
           break;
        }
      }
      /* use anonymous delegate
      string foundItem = _list.Find( delegate(string item) {
         found++;
         return string.Equals(search, item);
      });
      */
   }
   return found;
}
Run Code Online (Sandbox Code Playgroud)

LINQ对我来说是新的.我很好奇我是否可以使用LINQ来查找列表中的项目?怎么可能?

Rex*_*x M 451

有几种方法(注意这不是一个完整的清单).

1)Single将返回一个结果,但如果找不到或多于一个(可能是你想要的,也可能不是你想要的)会抛出异常:

string search = "lookforme";
List<string> myList = new List<string>();
string result = myList.Single(s => s == search);
Run Code Online (Sandbox Code Playgroud)

注意SingleOrDefault()将表现相同,除了它将为引用类型返回null,或者为值类型返回默认值,而不是抛出异常.

2)哪里将返回符合您条件的所有项目,因此您可以获得一个元素的IEnumerable:

IEnumerable<string> results = myList.Where(s => s == search);
Run Code Online (Sandbox Code Playgroud)

3)首先将返回符合您标准的第一项:

string result = myList.First(s => s == search);
Run Code Online (Sandbox Code Playgroud)

注意FirstOrDefault()将表现相同,除了它将为引用类型返回null,或者为值类型返回默认值,而不是抛出异常.

  • 很好的答案.我发现SingleOrDefault是我的选择答案 - 与Single相同但如果找不到则返回'null'. (33认同)
  • 关于使用SingleOrDefault需要注意的一点是,因为如果列表中有多个匹配项会抛出异常,它必须遍历每个项目,FirstOrDefault将在找到第一个匹配项后停止搜索.https://msdn.microsoft.com/en-us/library/bb342451(v=vs.110).aspx (4认同)
  • 我不知道Single()或SingleOrDefault().很有用. (2认同)

R. *_*des 71

如果你想要元素的索引,这将做到:

int index = list.Select((item, i) => new { Item = item, Index = i })
                .First(x => x.Item == search).Index;

// or
var tagged = list.Select((item, i) => new { Item = item, Index = i });
int index = (from pair in tagged
            where pair.Item == search
            select pair.Index).First();
Run Code Online (Sandbox Code Playgroud)

你不能在第一关中摆脱lambda.

请注意,如果该项目不存在,则会抛出此值.这通过诉诸可空的int来解决问题:

var tagged = list.Select((item, i) => new { Item = item, Index = (int?)i });
int? index = (from pair in tagged
            where pair.Item == search
            select pair.Index).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

如果你想要这个项目:

// Throws if not found
var item = list.First(item => item == search);
// or
var item = (from item in list
            where item == search
            select item).First();

// Null if not found
var item = list.FirstOrDefault(item => item == search);
// or
var item = (from item in list
            where item == search
            select item).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

如果要计算匹配的项目数:

int count = list.Count(item => item == search);
// or
int count = (from item in list
            where item == search
            select item).Count();
Run Code Online (Sandbox Code Playgroud)

如果您想要匹配的所有项目:

var items = list.Where(item => item == search);
// or
var items = from item in list
            where item == search
            select item;
Run Code Online (Sandbox Code Playgroud)

并且不要忘记null在任何这些情况下检查列表.

或者用(list ?? Enumerable.Empty<string>())而不是list.

感谢Pavel帮助评论.

  • 两点.首先,没有必要在这里使用`string.Equals` - 没有错误的`==`.其次,我还提到`FirstOrDefault`(对于可能不存在项的情况)和带有索引的`Select`,以涵盖需要项目索引的情况(就像在问题本身的样本中一样). (2认同)

Agi*_*Jon 13

如果真的是List<string>你不需要LINQ,只需使用:

int GetItemIndex(string search)
{
    return _list == null ? -1 : _list.IndexOf(search);
}
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找物品本身,请尝试:

string GetItem(string search)
{
    return _list == null ? null : _list.FirstOrDefault(s => s.Equals(search));
}
Run Code Online (Sandbox Code Playgroud)


Kel*_*sey 11

您想要列表中的项目还是实际项目本身(将假定项目本身).

以下是一些选项:

string result = _list.First(s => s == search);

string result = (from s in _list
                 where s == search
                 select s).Single();

string result = _list.Find(search);

int result = _list.IndexOf(search);
Run Code Online (Sandbox Code Playgroud)


Rck*_*kLN 6

这种方法更简单,更安全

var lOrders = new List<string>();
Run Code Online (Sandbox Code Playgroud)

bool insertOrderNew = lOrders.Find(r => r == "1234") == null ? true : false

  • 我认为我们甚至不需要下面的 `true : false` 应该工作相同 `bool insertOrderNew = lOrders.Find(r =&gt; r == "1234") == null;` (2认同)

Col*_*nic 5

怎么样IndexOf

搜索指定的对象并返回列表中第一个匹配项的索引

例如

> var boys = new List<string>{"Harry", "Ron", "Neville"};  
> boys.IndexOf("Neville")  
2
> boys[2] == "Neville"
True
Run Code Online (Sandbox Code Playgroud)

请注意,如果列表中未出现该值,则返回-1

> boys.IndexOf("Hermione")  
-1
Run Code Online (Sandbox Code Playgroud)