Como adicionar um novo item na matriz de string existente em C # .net?
Eu preciso preservar os dados existentes.
Como adicionar um novo item na matriz de string existente em C # .net?
Eu preciso preservar os dados existentes.
Respostas:
Eu usaria uma lista se você precisar de uma matriz de tamanho dinâmico:
List<string> ls = new List<string>();
ls.Add("Hello");
Isso poderia ser uma solução;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
Mas para uma matriz de tamanho dinâmico, prefiro a lista também.
Usando LINQ:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
Eu gosto de usar isso, pois é uma linha única e muito conveniente para incorporar uma instrução switch, uma instrução if simples ou passar como argumento.
EDITAR:
Algumas pessoas não gostam, new[] { newitem }porque cria uma matriz pequena e temporária de um item. Aqui está uma versão usando Enumerable.Repeatque não requer a criação de nenhum objeto (pelo menos não na superfície - os iteradores do .NET provavelmente criam vários objetos da máquina de estado sob a tabela).
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
E se você tiver certeza de que a matriz nunca nulldeve começar, pode simplificá-la para:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
Observe que se você deseja adicionar itens a uma coleção ordenada, Listprovavelmente é a estrutura de dados desejada, não uma matriz para começar.
Pergunta muito antiga, mas ainda queria adicionar isso.
Se você está procurando uma linha, pode usar o código abaixo. Ele combina o construtor da lista que aceita uma enumerável e a sintaxe do inicializador "novo" (desde que a pergunta foi levantada).
myArray = new List<string>(myArray) { "add this" }.ToArray();
Arrays em C # são imutáveis , por exemplo string[], int[]. Isso significa que você não pode redimensioná-los. Você precisa criar uma nova matriz.
Aqui está o 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 você pode ver, ele cria uma nova matriz com o novo tamanho, copia o conteúdo da matriz de origem e define a referência para a nova matriz. A dica para isso é a palavra-chave ref para o primeiro parâmetro.
Existem listas que podem alocar dinamicamente novos slots para novos itens. Isto é, por exemplo, Lista <T> . Eles contêm matrizes imutáveis e as redimensionam quando necessário (a Lista <T> não é uma implementação de lista vinculada!). ArrayList é a mesma coisa sem Genéricos (com matriz de objetos ).
LinkedList <T> é uma implementação real de lista vinculada. Infelizmente, você pode adicionar apenas elementos LinkListNode <T> à lista, portanto, você deve agrupar seus próprios elementos de lista nesse tipo de nó. Eu acho que seu uso é incomum.
Aray.Resizepode redimensionar uma matriz sem perder seu conteúdo. docs.microsoft.com/en-us/dotnet/api/…
Você pode expandir a resposta fornecida por @Stephen Chung usando sua lógica baseada em LINQ para criar um método de extensão usando um 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();
}
}
Você pode chamá-lo diretamente na matriz assim.
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...
}
É certo que o método AddRangeToArray () parece um pouco exagerado, pois você tem a mesma funcionalidade do Concat (), mas dessa forma o código final pode "trabalhar" diretamente com a matriz, em oposição a isso:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
se você trabalha muito com matrizes e não lista por algum motivo, esse método genérico de retorno digitado genérico Addpode ajudar
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 as respostas propostas fazem o mesmo que dizem que gostariam de evitar, criando uma nova matriz e adicionando uma nova entrada apenas com mais sobrecarga perdida. LINQ não é mágico, a lista de T é uma matriz com um espaço de buffer com algum espaço extra para evitar o redimensionamento da matriz interna quando itens são adicionados.
Todas as abstrações precisam resolver o mesmo problema, criar uma matriz sem slots vazios que contenham todos os valores e os retornem.
Se você precisar da flexibilidade e criar uma lista grande o suficiente para passar, faça isso. caso contrário, use uma matriz e compartilhe esse objeto seguro para threads. Além disso, o novo Span ajuda a compartilhar dados sem precisar copiar as listas.
Para responder à pergunta:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
Portanto, se você já possui uma matriz, minha solução rápida será
var tempList = originalArray.ToList();
tempList.Add(newitem);
Agora basta substituir a matriz original pela nova
originalArray = tempList.ToArray();
Um novo Append<TSource>método foi adicionado ao IEnumerable<TSource>.NET Framework 4.7.1 e .NET Core 1.0.
Aqui está como usá-lo:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
Observe que se você deseja adicionar o elemento no início da matriz, pode usar o novo Prepend<TSource>método.
Que tal usar um método de extensão? Por exemplo:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
por exemplo:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
Observe que isso imita esse comportamento da extensão Uniion do Linq (usado para combinar duas matrizes em uma nova) e exigia que a biblioteca Linq funcionasse.
Eu concordo com o Ed. O C # não facilita isso da maneira que o VB faz com o ReDim Preserve. Sem uma coleção, você terá que copiar a matriz para uma maior.
ReDim Preservesimplesmente copia a matriz para uma lager. Não há redimensionamento milagroso da 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 que não experimentar usando a classe Stringbuilder . Possui métodos como .inserir e .append. Você pode ler mais sobre isso aqui: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Como esta pergunta não está satisfeita com a resposta fornecida, gostaria de adicionar esta resposta :)
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;
}
}
}
}