Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

462
Vistas
C# Enumerable.Tomar con valor predeterminado

¿Cuál es la mejor manera de obtener exactamente valores x de un Enumerable en C#? Si uso Enumerable .Take() así:

 var myList = Enumerable.Range(0,10); var result = myList.Take(20);

El resultado solo tendrá 10 elementos.

Quiero llenar las entradas que faltan con un valor predeterminado. Algo como esto:

 var myList = Enumerable.Range(0,10); var result = myList.TakeOrDefault(20, default(int)); //Is there anything like this?

¿Existe tal función en C # y, de no ser así, cuál sería la mejor manera de lograrlo?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Podrías hacer algo como:

 var result = myList.Concat(Enumerable.Repeat(default(int), 20)).Take(20);

Y sería fácil convertir esto en un método de extensión:

 public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, T defaultValue) { return list.Concat(Enumerable.Repeat(defaultValue, count)).Take(count); }

Pero hay un problema sutil aquí. Esto funcionaría perfectamente bien para los tipos de valor , para un tipo de referencia, si su defaultValue no es nulo, está agregando el mismo objeto varias veces. Que probablemente no es lo que quieres. Por ejemplo, si tuvieras esto:

 var result = myList.TakeOrDefault(20, new Foo());

Vas a agregar la misma instancia de Foo para completar tu colección. Para resolver ese problema, necesitarías algo como esto:

 public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, Func<T> defaultFactory) { return list.Concat(Enumerable.Range(0, count).Select(i => defaultFactory())).Take(count); }

Que llamarías así:

 var result = myList.TakeOrDefault(20, () => new Foo())

Por supuesto, ambos métodos pueden coexistir, por lo que fácilmente podría tener:

 // pad a list of ints with zeroes var intResult = myIntList.TakeOrDefault(20, default(int)); // pad a list of objects with null var objNullResult = myObjList.TakeOrDefault(20, (object)null); // pad a list of Foo with new (separate) instances of Foo var objPadNewResult = myFooList.TakeOrDefault(20, () => new Foo());
over 4 years ago · Santiago Trujillo Denunciar

0

No está allí de forma predeterminada, pero es bastante fácil escribirlo como un método de extensión.

 public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> items, int count, T defaultValue) { var i = 0; foreach(var item in items) { i++; yield return item; if(i == count) yield break; } while(i++<count) { yield return defaultValue; } }

Ejemplo en vivo: http://rextester.com/XANF91263

over 4 years ago · Santiago Trujillo Denunciar

0

Lo que está buscando es un método PadTo de propósito general, que extiende la longitud de la colección si es necesario usando un valor dado.

 public static IEnumerable<T> PadTo<T>(this IEnumerable<T> source, int len) { return source.PadTo(len, default(T)); } public static IEnumerable<T> PadTo<T>(this IEnumerable<T> source, int len, T elem) { return source.PadTo(len, () => elem); } public static IEnumerable<T> PadTo<T>(this IEnumerable<T> source, int len, Func<T> elem) { int i = 0; foreach(var t in source) { i++; yield return t; } while(i++ < len) yield return elem(); }

Ahora puede expresar:

 myList.Take(20).PadTo(20);

Esto es análogo a la List[A].padTo

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda