Consulta Linq: busque cadenas basadas en la primera letra b / w dos rangos

Tenemos una lista que contiene nombres de países. Necesitamos encontrar los nombres de los países de la lista en blanco y negro con dos letras. Como nombres de todos los países cuyo nombre comienza en b / w AG y así sucesivamente. Creamos la siguiente consulta linq pero es fea.

var countryAG = from elements in countryList
where elements.StartsWith("A") || 
elements.StartsWith("B") || 
elements.StartsWith("C") || 
elements.StartsWith("D") || 
elements.StartsWith("E") || 
elements.StartsWith("F") || 
elements.StartsWith("G") || 
elements.StartsWith("H") 
select elements;

donde se crea countryList en C #

List< string> countryList = new List< string>();

¿Alguna ayuda o alguna otra forma eficiente de realizar la tarea anterior?

preguntado el 27 de agosto de 11 a las 19:08

¿Podemos suponer que los nombres de los países están en inglés y podemos usar el orden de clasificación en inglés? -

6 Respuestas

var countryAG = from elements in countryList
                where elements[0] >= 'A' && elements[0] <= 'H'
                select elements;

Los caracteres son solo números en realidad, por lo que puede compararlos como tales

Respondido 28 ago 11, 00:08

Esa consulta no se compilará, lo olvidaste select. - svick

Gracias @Steven, pero sigue el error durante la compilación: el cuerpo de una consulta debe terminar con una cláusula de selección o una cláusula de grupo - Malik

@svick, ¿dónde debo agregar seleccionar? - Malik

Trabajado como un encanto. Gracias @Steven. - Malik

Trabajado como un encanto. Gracias @svick por toda la ayuda. - Malik

No puedo probarlo ahora mismo, pero lo intentaría

countryList.Where((s) => s[0] <= 'A' && s[0] >= 'G');

Respondido 27 ago 11, 23:08

Puede usar una lista de prefijos y luego usar la lista de prefijos para comparar; de esta manera, puede usar fácilmente diferentes listas de prefijos según el rango que le interese:

 List<string> prefixList = new List<string>() { "A", "B", "C", "D", "E", "F", "G" };
 var countryAG = countryList.Where( x=> prefixList.Any( p => x.StartsWith(p)));

Respondido 27 ago 11, 23:08

Gracias @Broken, pero es el mismo que mi enfoque actual. No estoy interesado en escribir todos los alfabetos en inglés. - Malik

Trata

char[] startingLetters = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
var countryAG = 
    from elements in countryList 
    where elements.IndexOfAny(startingLetters, 0, 1) == 0 
    select elements;

Vea aquí para obtener información sobre IndexOfAny.

Respondido 27 ago 11, 23:08

Gracias @Yahia pero es el mismo que mi enfoque actual. No estoy interesado en escribir todos los alfabetos en inglés. - Malik

lamento leer eso, solicitó una forma más eficiente ... Apuesto a que la consulta de mi respuesta se ejecuta más rápido que la que está utilizando actualmente y, por lo tanto, lo sugerí ... - Yahia

Lo siento @Yahia. Ignoro el aspecto de la eficiencia ya que estaba construyendo sobre "simplificar las cosas" e ignoro la parte "eficiente". Lo siento de nuevo. Además, ¿tenemos alguna forma de "hacer las cosas simples y eficientes"? El escenario es simple, tenemos una lista de nombres de países y tenemos que dividirlos entre AG, IP y QZ. Pensé que Linq es rápido y fácil. Tus pensamientos por favor. - Malik

Intente usar este código:

var start = "a";
var end = "g";
var regex = new Regex(string.Format("^[{0}-{1}]", start, end));
var result = list.Where(x => regex.Match(x.ToLowerInvariant()).Success);

'inicio' y 'final' son estáticos como ejemplo.

Respondido 28 ago 11, 00:08

Usar expresiones regulares suena interesante. Le daré una oportunidad a esto. Gracias por su respuesta. - Malik

En lugar de Match().Success, puedes usar IsMatch(). - svick

Tengo dos funciones de extensión:

public static IEnumerable<char> Range(char start, char end)
{
  return Enumerable.Range((int)start, (int)end - (int)start + 1).Select(i => (char)i);
}

que crea una variedad de personajes, y

public static bool In(this string source, IEnumerable<string> collection)
{
  return collection.Contains(source);
}

que es solo el inverso de Contains, principalmente para facilitar la lectura.

Juntos puedo hacer:

where elements[0].In(Range('a', 'f')))

Respondido 22 Abr '17, 22:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.