2009-04-09 5 views
19

Использование LINQ, что является лучшим способом выбрать один элемент из списка, если элемент может не существовать в списке?Выберите один элемент из списка

У меня есть два решения, ни один из которых мне не нравится. Я использую предложение where, чтобы выбрать список элементов (который, как я знаю, будет только одним), я могу проверить счетчик и сделать одиночный вызов в этом списке, если счет один, другой выбор - использовать foreach и просто перерыв после получения предмета.

Ни один из них не кажется хорошим подходом, есть ли лучший способ?

ответ

32

Вы можете использовать IEnumerable.First() или IEnumerable.FirstOrDefault().

Разница в том, что First() будет метать, если элемент не найден (или если ни один элемент не соответствует условиям, если вы используете условия). FirstOrDefault() вернет default(T) (null если это ссылочный тип).

+1

Так просто, не уверен, как я пропустил его. Благодарю. – Daniel

+0

это действительно смущает, когда у нас есть список элементов, и мы хотим, чтобы один элемент из него основывался на условии (Where()), имя метода First/FirstOrDefault, документация указана - возвращает первый элемент последовательности или значение по умолчанию значение, если последовательность не содержит элементов. Что приходит в голову, так это то, что этот метод получит первый элемент в этом списке без перебора по списку. [ref] (https://msdn.microsoft.com/en-us/library/bb340482 (v = vs.110) .aspx) –

+0

@KuganKumar Он должен выполнять итерацию до тех пор, пока не найдет совпадение (или не достигнет конца и не сделает 't найти один) - это «первый элемент соответствия», а не «первый элемент коллекции», –

1

Возможно, мне что-то не хватает, но обычно вызов .SingleOrDefault() - это путь к возврату либо одного элемента в списке, либо значения по умолчанию (null для ссылочных или нулевых типов) - это список пуст. Генерирует исключение, если список содержит более одного элемента.

Используйте FirstOrDefault() позаботиться о том случае, когда вы могли бы иметь более одного)

8
List<string> items = new List<string>(); 

items.Find(p => p == "blah"); 

или

items.Find(p => p.Contains("b")); 

, но это позволяет определить, что вы ищете с помощью спичек предиката ...

Я думаю, если вы говорите linqToSql, то:

пример ищет счета ...

DataContext dc = new DataContext(); 

Account item = dc.Accounts.FirstOrDefault(p => p.id == 5); 

Если вам нужно, чтобы убедиться, что есть только один пункт (кидает исключение, когда более чем 1)

DataContext dc = new DataContext(); 

Account item = dc.Accounts.SingleOrDefault(p => p.id == 5); 
2

Есть два простых способа, в зависимости от если вы хотите иметь дело с исключениями или получить значение по умолчанию.

Вы можете использовать метод расширения First<T>() или FirstOrDefault<T>(), чтобы получить первый результат или default(T).

var list = new List<int> { 1, 2, 4 }; 
var result = list.Where(i => i == 3).First(); // throws InvalidOperationException 
var result = list.Where(i => i == 3).FirstOrDefault(); // = 0 
14

Используйте переключатель FirstOrDefault.

var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

var firstEven = list.FirstOrDefault(n => n % 2 == 0); 

if (firstEven == 0) 
    Console.WriteLine("no even number"); 
else 
    Console.WriteLine("first even number is {0}", firstEven); 

Просто передайте в предикате First или FirstOrDefault метод и счастливо объехать»список и выбирает первый матч для вас.

Если нет совпадения, FirstOrDefault вернет значение по умолчанию любого типа данных, в котором находятся элементы списка.

Надеется, что это помогает :-)

0

SingleOrDefault() является то, что вам нужно

веселят

4

Просто чтобы завершить ответ, если вы используете синтаксис LINQ, вы можете просто обернуть его, поскольку он возвращает IEnumerable:

(from int x in intList 
where x > 5 
select x * 2).FirstOrDefault() 
0

только что видел это сейчас, если вы работаете со списком объекта, который вы можете попробовать это

public class user 
{ 
    public string username { get; set; } 
    public string password { get; set; } 
} 

    List<user> userlist = new List<user>(); 

     userlist.Add(new user { username = "macbruno", password = "1234" }); 
     userlist.Add(new user { username = "james", password = "5678" }); 
     string myusername = "james"; 
     string mypassword = "23432"; 

    user theUser = userlist.Find(
      delegate (user thisuser) 
      { 
       return thisuser.username== myusername && thisuser.password == mypassword; 
      } 
      ); 

      if (theUser != null) 
      { 
       Dosomething(); 
      } 
      else 
      { 
       DoSomethingElse(); 

      } 
Смежные вопросы