LINQ의 List에서 항목을 찾으십니까?


226

다음은 문자열 목록에서 항목을 찾는 간단한 예입니다. 일반적으로 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;
}

LINQ는 나에게 새로운 것입니다. LINQ를 사용하여 목록에서 항목을 찾을 수 있는지 궁금합니다. 가능하다면 어떻게?


훌륭합니다. 그러나 이것들은 모두 람다 식 스타일입니다. 여기에 간단한 목록을 사용합니다. 이 목록은 여러 속성을 가진 클래스 일 수 있으며 일부는 검색에 사용됩니다. LINQ에서 검색하는 방법은 "from .. in ... where ... select ..."
David.Chu.ca

아냐, 미안 이러한 대부분의 메소드 (First, Single, Any, ...)는 해당 양식 으로 직접 변환 할 수 없습니다 .
R. Martinho Fernandes

사실, 당신은 몇 가지 경우에 람다를 제거 할 수 있습니다 ...
R. Martinho Fernandes

좋은 답변입니다! 열거 형 사례에서 LINQ 검색을 맛보고 싶습니다.
David.Chu.ca

답변:


478

몇 가지 방법이 있습니다 ( 전체 목록 이 아님 ).

1) Single 은 단일 결과를 반환하지만 하나 이상을 찾지 못하면 예외를 throw합니다 (원하는 결과 일 수도 있고 아닐 수도 있음).

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

참고 SingleOrDefault()는 예외를 throw하는 대신 참조 유형의 경우 null을 반환하거나 값 유형의 기본값을 반환한다는 점을 제외하고는 동일하게 작동합니다.

2) 어디에서 기준과 일치하는 모든 항목을 반환하므로 하나의 요소로 IEnumerable을 얻을 수 있습니다.

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

3) 먼저 기준과 일치하는 첫 번째 항목을 반환합니다.

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

참고 FirstOrDefault()는 예외를 throw하는 대신 참조 유형의 경우 null을 반환하거나 값 유형의 기본값을 반환한다는 점을 제외하고는 동일하게 작동합니다.


35
좋은 대답입니다. SingleOrDefault가 내 선택의 답으로 발견되었습니다-Single과 동일하지만 찾을 수 없으면 'null'을 반환합니다.
Eddie Parker

2
Single () 또는 SingleOrDefault ()를 몰랐습니다. 굉장히 유용하다.
draconis

이러한 메소드를 다른 콜렉션과 같이 ReadOnlyCollection또는 같이 사용할 수 있습니까 ObservableCollection?
yellavon

@yellavon 이들은 다음을 구현하는 모든 유형의 확장 메소드 IEnumerable<T>이거나IQueryable<T>
Rex M

4
SingleOrDefault를 사용할 때주의해야 할 점은 목록에 둘 이상의 일치 항목이 있으면 예외가 발생하기 때문에 모든 항목을 반복해야한다는 것입니다. 첫 번째 일치 항목이 발견되면 FirstOrDefault가 검색을 중지합니다. msdn.microsoft.com/ko-kr/library/bb342451(v=vs.110).aspx
DavidWainwright

73

요소의 색인을 원하면 다음과 같이하십시오.

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

첫 패스에서는 람다를 제거 할 수 없습니다.

아이템이 존재하지 않으면 던질 것입니다. 이것은 nullable 정수에 의지하여 문제를 해결합니다.

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

당신이 항목을 원하는 경우 :

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

일치하는 항목 수를 계산하려면 다음을 수행하십시오.

int count = list.Count(item => item == search);
// or
int count = (from item in list
            where item == search
            select item).Count();

일치하는 모든 항목을 원하는 경우 :

var items = list.Where(item => item == search);
// or
var items = from item in list
            where item == search
            select item;

null이 경우 목록을 확인하는 것을 잊지 마십시오 .

또는 (list ?? Enumerable.Empty<string>())대신 사용하십시오 list.

의견에 도움을 준 Pavel에게 감사드립니다.


2
두 점. 첫째, string.Equals여기서 사용할 필요가 없습니다 ==. 둘째, FirstOrDefault(항목이 없을 수도있는 경우) 언급하고 항목 자체의 Select색인이 필요한 경우 (질문 자체의 샘플에서 와 같이 ) 를 다루는 색인이 있습니다.
Pavel Minaev

나는 아직 행복하지 않다. 내 예제에는 -1 색인 (찾을 수 없음)이 없습니다. 어떠한 제안?
R. Martinho Fernandes

먼저 존재 여부를 확인하는 것 외에도.
R. Martinho Fernandes

list가 null인지 먼저 확인해야합니까?
David.Chu.ca

ArgumentNullException소스가 null 인 경우 선택 던지기
R. Martinho Fernandes

13

정말로 List<string>LINQ가 필요하지 않은 경우 다음을 사용하십시오.

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

항목 자체를 찾고 있다면 다음을 시도하십시오.

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

1
첫 번째 예의 논리에 따라 두 번째 예를 사용할 수 있습니다 _list.Find(search).
jwg

12

목록에있는 항목이나 실제 항목 자체를 원하십니까 (항목 자체를 가정 함).

다음은 다양한 옵션입니다.

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

우와 ... 어떤 사람들은 초고속 트리거입니다.)
Kelsey

반환 값으로 인덱스는 어떻습니까?
David.Chu.ca

_list가 from .. in _list ... 형식으로 null인지 확인해야합니까?
David.Chu.ca

6

이 방법은 더 쉽고 안전합니다

var lOrders = new List<string>();

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


1
우리는 true : false아래 에서도 동일하게 작동 하지 않아도된다고 생각 합니다 bool insertOrderNew = lOrders.Find(r => r == "1234") == null;
Vbp

5

어때요 IndexOf?

지정된 객체를 검색하고 목록 내에서 처음 나타나는 색인을 반환합니다.

예를 들어

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

값이 목록에 없으면 -1을 반환합니다.

> boys.IndexOf("Hermione")  
-1

2

필자가 원할 때 정확히 원하는 것을 제공하는 일종의 색인 목록 인 Dictionary를 사용했습니다.

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

예를 들어, 여백 값에 액세스하려고 할 때마다 사전을 처리합니다.

int xStartPos = margins["left"];
int xLimitPos = margins["right"];
int yStartPos = margins["top"];
int yLimitPos = margins["bottom"];

따라서 수행중인 작업에 따라 사전이 유용 할 수 있습니다.


다른 질문에 대한 훌륭한 답변.
jwg

2

LINQ를 사용하도록 메소드를 다시 작성하는 방법은 다음과 같습니다.

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

이 코드를 사용해보십시오 :

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

1

목록에서 요소를 찾아야하는 경우 Findand FindAllextensions 메소드를 사용할 수 있지만 그 사이에는 약간의 차이가 있습니다. 다음은 예입니다.

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

1

Linq List 검색에서 첫 번째 또는 기본값을 얻는 데 도움이됩니다.

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

이 검색은 반환 할 첫 번째 또는 기본값을 찾습니다.


0

객체 목록에서 객체를 검색하려고합니다.

Linq List 검색에서 첫 번째 또는 기본값을 얻는 데 도움이됩니다.

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

또는

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

0

Where Linq 확장과 함께 FirstOfDefault를 사용하면 IEnumerable에서 MessageAction 클래스를 가져올 수 있습니다. me

var action = Message.Actions.Where (e => e.targetByName == className) .FirstOrDefault ();

어디

조치 목록 {get; 세트; }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.