2009-04-09 23 views
19

Usando LINQ ¿cuál es la mejor manera de seleccionar un solo elemento de una lista si el artículo no puede existir en la lista?Seleccionar un solo elemento de una lista

He encontrado dos soluciones, ninguna de las cuales me gusta. Utilizo una cláusula where para seleccionar la lista de elementos (que sé que solo será uno), luego puedo verificar el recuento y hacer una sola llamada en esta lista si el recuento es uno, la otra opción es usar un foreach y solo romper después de obtener el artículo.

Ninguno de estos parece un buen enfoque, ¿hay una mejor manera?

Respuesta

32

Puede usar IEnumerable.First() o IEnumerable.FirstOrDefault().

La diferencia es que First() arrojará si no se encuentra ningún elemento (o si ningún elemento coincide con las condiciones, si utiliza las condiciones). FirstOrDefault() devolverá default(T) (null si es un tipo de referencia).

+1

Tan simple, no estoy seguro de cómo me lo perdí. Gracias. – Daniel

+0

realmente confunde, cuando tenemos una Lista de elementos y deseamos que un elemento se base en una condición (Donde()), el nombre del método es Primero/PrimeroDePor defecto, la documentación dice - Devuelve el primer elemento de una secuencia, o un valor predeterminado valor si la secuencia no contiene elementos. Lo que viene a la mente es que este método obtendrá el primer elemento en esa lista sin iterar a través de la lista. [ref] (https://msdn.microsoft.com/en-us/library/bb340482 (v = vs.110) .aspx) –

+0

@KuganKumar Tiene que iterar hasta que encuentre una coincidencia (o llegue al final y no lo haga) 't encontrar uno) - es el "primer elemento coincidente", no "primer elemento de la colección" –

1

Quizás me falta algo aquí, pero generalmente llamar al .SingleOrDefault() es el camino a seguir para devolver el elemento único en la lista, o un valor predeterminado (nulo para referencia o tipos anulables) es que la lista está vacía. Genera una excepción si la lista contiene más de un elemento.

Uso FirstOrDefault() cuidar el caso de que usted podría tener más de una)

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

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

o

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

pero esto le permite definir lo que busca a través de un predicado partido ...

Supongo que si estás hablando de linqToSql entonces:

ejemplo en busca de cuenta ...

DataContext dc = new DataContext(); 

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

Si usted necesita para asegurarse de que sólo hay 1 artículo (lanza una excepción cuando más de 1)

DataContext dc = new DataContext(); 

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

Hay dos formas sencillas, dependiendo de si quieres lidiar con excepciones u obtener un valor predeterminado.

Puede usar el método de extensión First<T>() o FirstOrDefault<T>() para obtener el primer resultado o 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

Use el selector 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); 

sólo tiene que pasar en un predicado con el métodoFirst o FirstOrDefault y va a viajar feliz por' la lista y recoge el primer partido para usted.

Si no hay coincidencia, FirstOrDefault devolverá el valor predeterminado de cualquier tipo de datos que sean los elementos de la lista.

Esperanza esto ayuda :-)

0

SingleOrDefault() es lo que necesita

aplausos

4

sólo para completar la respuesta, Si está utilizando la sintaxis de LINQ, sólo puede envolverlo ya que devuelve IEnumerable:

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

acaba de ver esto ahora, si se está trabajando con una lista de objetos puede probar esta

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

      } 
Cuestiones relacionadas