Por ejemplo:¿Hay una declaración a anteponer un elemento T a un IEnumerable <T>
string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = ???; //singleList yields 'a', 'b', 'c', 'd'
Por ejemplo:¿Hay una declaración a anteponer un elemento T a un IEnumerable <T>
string element = 'a';
IEnumerable<string> list = new List<string>{ 'b', 'c', 'd' };
IEnumerable<string> singleList = ???; //singleList yields 'a', 'b', 'c', 'd'
¿Puedo entender que pueda no sólo Insert
en la lista existente?
Bueno, podría usar new[] {element}.Concat(list)
.
De lo contrario, se podría escribir su propio método de extensión:
public static IEnumerable<T> Prepend<T>(
this IEnumerable<T> values, T value) {
yield return value;
foreach (T item in values) {
yield return item;
}
}
...
var singleList = list.Prepend("a");
No, no hay tal incorporado DECLARACIÓN, declaración, pero es trivial para implementar dicha función:
IEnumerable<T> PrependTo<T>(IEnumerable<T> underlyingEnumerable, params T[] values)
{
foreach(T value in values)
yield return value;
foreach(T value in underlyingEnumerable)
yield return value;
}
IEnumerable<string> singleList = PrependTo(list, element);
Puede incluso conviértalo en un método de extensión si la versión de C# lo permite.
Puede rodar su propia:
static IEnumerable<T> Prepend<T>(this IEnumerable<T> seq, T val) {
yield return val;
foreach (T t in seq) {
yield return t;
}
}
y luego usarlo:
IEnumerable<string> singleList = list.Prepend(element);
Creo que debería ser "yield return t" dentro del foreach y el método debe ser estático –
public static class IEnumerableExtensions
{
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> ie, T item)
{
return new T[] { item }.Concat(ie);
}
}
Parece que me gusta que está haciendo coincidir el elemento hasta el final, no anteponiéndolo ... –
Vaya, buen punto. Editaré ... – BFree
Esto lo haría ...
IEnumerable<string> singleList = new[] {element}.Concat(list);
Si quería la SingleList para ser una lista, entonces ...
IEnumerable<string> singleList = new List<string>() {element}.Concat(list);
... funciona también.
también:
IEnumerable<string> items = Enumerable.Repeat(item, 1).Concat(list);
Me resulta conveniente para poder anteponer varios elementos de una manera chainable. Esta versión aprovecha los métodos de extensión y params
.
Como nota, esta versión permite implícitamente null
, pero es tan fácil cambiarla a throw new NullReferenceException()
si ese es el comportamiento deseado.
public static class IEnumerableExtensions
{
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, params T[] items)
{
return items.Concat(source ?? new T[0]);
}
}
permite una sintaxis muy legible para los artículos individuales:
GetItems().Prepend(first, second, third);
... y para colecciones de artículos:
GetItems().Prepend(GetMoreItems());
acabado el ejemplo de los resultados de la pregunta en:
string element = "a";
IEnumerable<string> list = new List<string>{ "b", "c", "d" };
IEnumerable<string> singleList = list.Prepend(element);
Solo como un recordatorio - Lista < T> no es el único tipo de contenedor. Si se encuentra agregando elementos al frente de la lista con bastante frecuencia, también puede considerar usar Pila < T> para implementar su contenedor.Una vez que tenga una pila
var container = new Stack<string>(new string[] { "b", "c", "d" });
siempre se puede "anteponer" un elemento a través
container.Push("a");
y seguir utilizando la colección como IEnumerable < T> como en
foreach (var s in container)
// do sth with s
además todos los otros métodos típicos para una pila como Pop(), Peek(), ...
Algunas de las soluciones anteriores se repiten en todo el IEnumeration < T> solo para anteponer un elemento (o más de uno en uno). Esta puede ser una operación muy costosa si su colección contiene una gran cantidad de elementos y la frecuencia de antemano es relativamente alta.
Al mirar algunos de los ejemplos, creo que preferiría invertir la extensión para aplicarla al objeto.
public static IEnumerable<T> PrependTo<T>(this T value, IEnumerable<T> values) {
return new[] { value }.Concat(values);
}
utilizado como
var singleList = element.PrependTo(list);
En .NET Core es una función de: '' '' public static System.Collections.Generic.IEnumerable Anteponer (esto System.Collections.Generic.IEnumerable fuente, elemento TSource); '' '' (https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.prepend?view=netcore-2.0) –
Y como parte de la implementación .Net Standard 2.0, está incluido en .Net 4.7.1. – NetMage