¿Cómo agregar un nuevo elemento en una matriz de cadenas existente en C # .net?
Necesito preservar los datos existentes.
¿Cómo agregar un nuevo elemento en una matriz de cadenas existente en C # .net?
Necesito preservar los datos existentes.
Respuestas:
Usaría una Lista si necesita una matriz de tamaño dinámico:
List<string> ls = new List<string>();
ls.Add("Hello");
Eso podría ser una solución;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
Pero para una matriz de tamaño dinámico, también preferiría la lista.
Usando LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
Me gusta usar esto, ya que es de una sola línea y muy conveniente para incrustar en una declaración de cambio, una simple declaración if o pasar como argumento.
EDITAR:
A algunas personas no les gusta new[] { newitem }porque crea una pequeña matriz temporal de un solo elemento. Aquí hay una versión Enumerable.Repeatque no requiere la creación de ningún objeto (al menos no en la superficie; los iteradores de .NET probablemente crean un montón de objetos de máquina de estado debajo de la tabla).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
Y si está seguro de que la matriz nunca nullcomenzará, puede simplificarla para:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Tenga en cuenta que si desea agregar elementos a una colección ordenada, Listprobablemente sea la estructura de datos que desea, no una matriz para comenzar.
Pregunta muy antigua, pero todavía quería agregar esto.
Si está buscando una línea, puede usar el siguiente código. Combina el constructor de la lista que acepta una sintaxis de inicializador enumerable y la "nueva" (desde la pregunta planteada).
myArray = new List<string>(myArray) { "add this" }.ToArray();
Las matrices en C # son inmutables , por ejemplo string[], int[]. Eso significa que no puede cambiar su tamaño. Necesita crear una nueva gama.
Aquí está el código para Array.Resize :
public static void Resize<T>(ref T[] array, int newSize)
{
if (newSize < 0)
{
throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
T[] sourceArray = array;
if (sourceArray == null)
{
array = new T[newSize];
}
else if (sourceArray.Length != newSize)
{
T[] destinationArray = new T[newSize];
Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
array = destinationArray;
}
}
Como puede ver, crea una nueva matriz con el nuevo tamaño, copia el contenido de la matriz de origen y establece la referencia a la nueva matriz. La sugerencia para esto es la palabra clave ref para el primer parámetro.
Hay listas que pueden asignar dinámicamente nuevos espacios para nuevos elementos. Esto es, por ejemplo, Lista <T> . Estos contienen matrices inmutables y los redimensionan cuando es necesario (¡List <T> no es una implementación de lista vinculada!). ArrayList es lo mismo sin Generics (con Object array).
LinkedList <T> es una implementación real de la lista vinculada. Desafortunadamente, puede agregar solo elementos LinkListNode <T> a la lista, por lo que debe ajustar sus propios elementos de lista en este tipo de nodo. Creo que su uso es poco común.
Aray.Resizepuede cambiar el tamaño de una matriz sin perder su contenido. docs.microsoft.com/en-us/dotnet/api/…
Puede ampliar la respuesta proporcionada por @Stephen Chung utilizando su lógica basada en LINQ para crear un método de extensión utilizando un tipo genérico.
public static class CollectionHelper
{
public static IEnumerable<T> Add<T>(this IEnumerable<T> sequence, T item)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(new[] { item });
}
public static T[] AddRangeToArray<T>(this T[] sequence, T[] items)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(items).ToArray();
}
public static T[] AddToArray<T>(this T[] sequence, T item)
{
return Add(sequence, item).ToArray();
}
}
Luego puede llamarlo directamente en la matriz de esta manera.
public void AddToArray(string[] options)
{
// Add one item
options = options.AddToArray("New Item");
// Add a
options = options.AddRangeToArray(new string[] { "one", "two", "three" });
// Do stuff...
}
Es cierto que el método AddRangeToArray () parece un poco exagerado ya que tiene la misma funcionalidad con Concat (), pero de esta manera el código final puede "funcionar" directamente con la matriz en lugar de esto:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
si está trabajando mucho con matrices y no con listas por alguna razón, este método genérico de devolución con tipo genérico Addpodría ayudarlo
public static T[] Add<T>(T[] array, T item)
{
T[] returnarray = new T[array.Length + 1];
for (int i = 0; i < array.Length; i++)
{
returnarray[i] = array[i];
}
returnarray[array.Length] = item;
return returnarray;
}
Todas las respuestas propuestas hacen lo mismo que dicen que les gustaría evitar, crean una nueva matriz y agregan una nueva entrada solo con la pérdida de más sobrecarga. LINQ no es mágico, la lista de T es una matriz con un espacio de búfer con algo de espacio adicional para evitar cambiar el tamaño de la matriz interna cuando se agregan elementos.
Todas las abstracciones tienen que resolver el mismo problema, crear una matriz sin espacios vacíos que contengan todos los valores y los devuelvan.
Si necesita la flexibilidad y puede crear una lista lo suficientemente grande que puede usar para pasar, hágalo. de lo contrario, use una matriz y comparta ese objeto seguro para subprocesos. Además, el nuevo Span ayuda a compartir datos sin tener que copiar las listas.
Para responder la pregunta:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Entonces, si tiene una matriz existente, mi solución rápida será
var tempList = originalArray.ToList();
tempList.Add(newitem);
Ahora solo reemplace la matriz original con la nueva
originalArray = tempList.ToArray();
Se Append<TSource>ha agregado un nuevo método IEnumerable<TSource>desde .NET Framework 4.7.1 y .NET Core 1.0.
Aquí está cómo usarlo:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Tenga en cuenta que si desea agregar el elemento al comienzo de la matriz, puede utilizar el nuevo Prepend<TSource>método.
¿Qué pasa con el uso de un método de extensión? Por ejemplo:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
por ejemplo:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Tenga en cuenta que esto imita este comportamiento de la extensión Uniion de Linq (utilizada para combinar dos matrices en una nueva), y requiere la biblioteca Linq para funcionar.
Estoy de acuerdo con Ed. C # no lo hace tan fácil como lo hace VB con ReDim Preserve. Sin una colección, tendrá que copiar la matriz en una más grande.
ReDim Preservesimplemente copia la matriz en una lager. No hay cambio milagroso de matriz.
string str = "string ";
List<string> li_str = new List<string>();
for (int k = 0; k < 100; i++ )
li_str.Add(str+k.ToString());
string[] arr_str = li_str.ToArray();
private static string[] GetMergedArray(string[] originalArray, string[] newArray)
{
int startIndexForNewArray = originalArray.Length;
Array.Resize<string>(ref originalArray, originalArray.Length + newArray.Length);
newArray.CopyTo(originalArray, startIndexForNewArray);
return originalArray;
}
¿Por qué no probar usando la clase Stringbuilder ? Tiene métodos como .insert y .append. Puede leer más sobre esto aquí: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Dado que esta pregunta no está satisfecha con la respuesta proporcionada, me gustaría agregar esta respuesta :)
public class CustomArrayList<T>
{
private T[] arr; private int count;
public int Count
{
get
{
return this.count;
}
}
private const int INITIAL_CAPACITY = 4;
public CustomArrayList(int capacity = INITIAL_CAPACITY)
{
this.arr = new T[capacity]; this.count = 0;
}
public void Add(T item)
{
GrowIfArrIsFull();
this.arr[this.count] = item; this.count++;
}
public void Insert(int index, T item)
{
if (index > this.count || index < 0)
{
throw new IndexOutOfRangeException( "Invalid index: " + index);
}
GrowIfArrIsFull();
Array.Copy(this.arr, index, this.arr, index + 1, this.count - index);
this.arr[index] = item; this.count++; }
private void GrowIfArrIsFull()
{
if (this.count + 1 > this.arr.Length)
{
T[] extendedArr = new T[this.arr.Length * 2];
Array.Copy(this.arr, extendedArr, this.count);
this.arr = extendedArr;
}
}
}
}