关于c#:在LINQ中查找List中的项目?

Find an item in List by LINQ?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}

Linq对我来说是新的。我很好奇是否可以用LINQ在列表中查找项目?如果可能怎么办?


有几种方法(注意这不是一个完整的列表)。

1)single将返回单个结果,但如果它发现一个或多个结果(可能是或可能不是您想要的结果),则会引发异常:

1
2
3
string search ="lookforme";
List<string> myList = new List<string>();
string result = myList.Single(s => s == search);

注:SingleOrDefault()的行为相同,只是它将为引用类型返回空值,或者为值类型返回默认值,而不是引发异常。

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

1
IEnumerable<string> results = myList.Where(s => s == search);

3)First将返回符合您条件的第一个项目:

1
string result = myList.First(s => s == search);

注:FirstOrDefault()的行为相同,只是它将为引用类型返回空值,或者为值类型返回默认值,而不是引发异常。


如果需要元素的索引,这将执行以下操作:

1
2
3
4
5
6
7
8
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();

你不能在第一次传球中就摆脱lambda。

请注意,如果该项不存在,则此操作将引发。这通过使用可以为空的int来解决问题:

1
2
3
4
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();

如果您想要物品:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 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();

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

1
2
3
4
5
int count = list.Count(item => item == search);
// or
int count = (from item in list
            where item == search
            select item).Count();

如果要匹配的所有项目:

1
2
3
4
5
var items = list.Where(item => item == search);
// or
var items = from item in list
            where item == search
            select item;

在这些情况下,不要忘记检查EDOCX1[0]的列表。

或者用(list ?? Enumerable.Empty())代替list

感谢帕维尔在评论中的帮助。


如果它确实是一个List,您不需要linq,只需使用:

1
2
3
4
int GetItemIndex(string search)
{
    return _list == null ? -1 : _list.IndexOf(search);
}

如果要查找项目本身,请尝试:

1
2
3
4
string GetItem(string search)
{
    return _list == null ? null : _list.FirstOrDefault(s => s.Equals(search));
}


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

以下是一系列选项:

1
2
3
4
5
6
7
8
9
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);


这种方法更简单更安全

1
var lOrders = new List<string>();

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


埃多克斯1〔7〕怎么样?

Searches for the specified object and returns the index of the first occurrence within the list

例如

1
2
3
4
5
> var boys = new List<string>{"Harry","Ron","Neville"};  
> boys.IndexOf("Neville")  
2
> boys[2] =="Neville"
True

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

1
2
> boys.IndexOf("Hermione")  
-1


以下是重写方法以使用LINQ的一种方法:

1
2
3
4
5
6
7
8
9
public static int GetItemIndex(string search)
{
    List<string> _list = new List<string>() {"one","two","three" };

    var result = _list.Select((Value, Index) => new { Value, Index })
            .SingleOrDefault(l => l.Value == search);

    return result == null ? -1 : result.Index;
}

因此,称之为

GetItemIndex("two")返回1

GetItemIndex("notthere")将返回-1

参考:linqsamples.com


我曾经用过一本字典,它是一种索引列表,当我想要它的时候,它会给我确切的我想要的东西。

1
2
3
4
5
Dictionary<string, int> margins = new Dictionary<string, int>();
margins.Add("left", 10);
margins.Add("right", 10);
margins.Add("top", 20);
margins.Add("bottom", 30);

例如,每当我想访问我的页边距值时,我都会在字典中添加地址:

1
2
3
4
int xStartPos = margins["left"];
int xLimitPos = margins["right"];
int yStartPos = margins["top"];
int yLimitPos = margins["bottom"];

所以,根据你所做的,字典可能是有用的。


如果我们需要从列表中找到一个元素,那么我们可以使用FindFindAll扩展方法,但是它们之间有细微的区别。下面是一个例子。

1
2
3
4
5
6
 List<int> items = new List<int>() { 10, 9, 8, 4, 8, 7, 8 };

  // It will return only one 8 as Find returns only the first occurrence of matched elements.
     var result = items.Find(ls => ls == 8);      
 // this will returns three {8,8,8} as FindAll returns all the matched elements.
      var result1 = items.FindAll(ls => ls == 8);

这将帮助您在LINQ列表搜索中获取第一个或默认值。

1
var results = _List.Where(item => item == search).FirstOrDefault();

此搜索将找到它将返回的第一个或默认值。


试试这个代码:

1
return context.EntitytableName.AsEnumerable().Find(p => p.LoginID.Equals(loginID) && p.Password.Equals(password)).Select(p => new ModelTableName{ FirstName = p.FirstName, UserID = p.UserID });


要在对象列表中搜索对象。

这将帮助您在LINQ列表搜索中获取第一个或默认值。

1
var item = list.FirstOrDefault(items =>  items.Reference == ent.BackToBackExternalReferenceId);

1
2
3
var item = (from items in list
    where items.Reference == ent.BackToBackExternalReferenceId
    select items).FirstOrDefault();