Como estender as matrizes em C#
Pergunta
Eu tenho que fazer um exercício usando matrizes. O usuário deve inserir 3 entradas (cada vez, informações sobre itens) e as entradas serão inseridas na matriz. Então eu devo exibir a matriz.
No entanto, estou tendo dificuldade em aumentar o comprimento da matriz sem alterar as informações nela; E como posso permitir que o usuário insira outro conjunto de entrada? É isso que tenho até agora:
public string stockNum;
public string itemName;
public string price;
string[] items = new string[3];
public string [] addItem(string[] items)
{
System.Console.WriteLine("Please Sir Enter the stock number");
stockNum = Console.ReadLine();
items.SetValue(stockNum, 0);
System.Console.WriteLine("Please Sir Enter the price");
price = Console.ReadLine();
items.SetValue(price, 1);
System.Console.WriteLine("Please Sir Enter the item name");
itemName = Console.ReadLine();
items.SetValue(itemName, 2);
Array.Sort(items);
return items;
}
public void ShowItem()
{
addItem(items);
Console.WriteLine("The stock Number is " + items[0]);
Console.WriteLine("The Item name is " + items[2]);
Console.WriteLine("The price " + items[1]);
}
static void Main(string[] args)
{
DepartmentStore depart = new DepartmentStore();
string[] ar = new string[3];
// depart.addItem(ar);
depart.ShowItem();
}
Então minha pergunta se resume a:
Como posso permitir que o usuário insira mais de um lote de entrada? Por exemplo, na primeira vez que o usuário inserirá as informações sobre o item (número do soquete, preço e nome), mas preciso permitir que o usuário insira mais informações sobre outro item?
Como posso exibir o soquete Num, preço e nome para cada item na matriz com base na suposição de que tenho mais de um item na matriz?
Solução
No .NET (C#), uma matriz não é redimensionável. Não é como em JavaScript ou PHP ter sido uma matriz é muito flexível e pode ser estendida com elementos arbitrários.
Por definição, uma matriz estática padrão possui um tamanho de correção, para que você possa fazer referência a um elemento usando o índice. ( http://en.wikipedia.org/wiki/array_data_structure#array_resizing ) Mas lá você pode ler sobre matriz dinâmica. Em C#, será o System.Collection.ArrayList-Object. ( http://en.wikipedia.org/wiki/dynamic_array )
Então, o que você precisa é da definição do Arraylist ou de uma lista ou lista genérica normal. (System.Collections.Genic.List)
string[] items = new string[3] { "input1", "input2", "input3" };
string[] moreItems = new string[10] { "input4", "input5" };
// array to list
List<string> itemsList = items.ToList<string>();
itemsList.Add("newItem");
// or merge an other array to the list
itemsList.AddRange(moreItems);
// list to array
string[] newArray = itemsList.ToArray();
Outras dicas
Começando com o .NET Framework 3.5, para matrizes unidimensionais que você pode usar Array.Resize<T>
método:
int[] myArray = { 1, 2, 3 };
Array.Resize(ref myArray, 5);
Link msdn é aqui.
Eu acho que você pode estar resolvendo o problema errado ...
Considere que os três itens (número de estoque, preço e nome) fazem parte de um objeto maior. Por enquanto podemos simplesmente chamá -lo item
. Queremos armazenar vários item
s em uma lista ou matriz. Considere usar uma abordagem orientada a objetos como esta:
class Widget
{
public int StockNum;
public int Price;
public string Name;
Widget(stockNum, price, name)
{
this.StockNum= stockNum;
this.Price = price;
this.Name = name;
}
}
Agora, você pode instanciar uma lista desses objetos:
List<Widget> items = new List<Widget>();
E adicione itens a eles:
for (int i = 0; i < 5; i++)
{
//Get input from user
System.Console.WriteLine("Please Sir Enter the stock number");
stockNum= Convert.ToInt32(Console.ReadLine()); //This isn't very safe...
System.Console.WriteLine("Please Sir Enter the price");
price = Convert.ToInt32(Console.ReadLine()); //This isn't very safe...
System.Console.WriteLine("Please Sir Enter the item name");
name = Console.ReadLine();
//Then add it to a new object
Widget item = new Widget(stockNum, price, name);
//And add this item to a list
items.Add(item);
}
Supondo que sua tarefa exige que você use matrizes e não outras aulas de coleção, você terá que fazer as coisas da maneira mais difícil.
As matrizes são imutáveis, ou seja, você não pode alterá -las depois de terem sido criadas. Você pode alterar o conteúdo, mas não o tamanho da matriz. Se você precisar crescer ou encolher a matriz, precisará criar uma nova matriz com o novo número de itens e copiar os itens que deseja da matriz antiga para a nova matriz.
Por exemplo, suponha que você queira pegar uma matriz e copiar apenas os elementos uniformes.
int[] a = new int[] {0,1,2,3,4,5,6,7,8,9};
int[] a2 = new int[a.Length / 2];
int counter = 0;
for (int i = 0; i < a.Length; i = i + 2)
{
a2[counter++] = a[i];
}
Então, você sempre pode atribuir A2 de volta a um
a = a2;
Você pode usar System.Collections.Generic.List<T>
que fornece uma coleção redimensível que também possui um .ToArray()
Método para retornar uma matriz comum, se você precisar.
Use uma lista e converta em uma matriz.
De fato, neste exemplo, você deve ter uma classe ou estrutura para StockInfo {Número de estoque, preço, nome do item}, então você deve inserir os dados em uma lista. Por fim, você pode converter para StockInfo [] usando o método ToArray da lista.
Você pode usar Arraylist em vez de? Ele será redimensionado conforme necessário.
Eu tive o mesmo problema, mas não consegui mudar o tipo e tive que ficar com a matriz desde que eu estava estendendo uma classe de API existente. Aqui está um método de modelo simples que estende uma matriz existente:
public static T[] ExtendArray<T> ( T[] array , uint index) where T:new()
{
List<T> list = new List<T>();
list.AddRange(array);
while (list.Count < index) {
list.Add(new T());
}
return list.ToArray();
}
Observe que o acima também inicializa os elementos com o construtor padrão.
Você pode contornar o 'problema' de não ser capaz de redimensionar as matrizes usando uma matriz tão grande quanto a maior matriz que você espera ter. Observe que isso é considerado hacking, não programação estruturada!
Se você tiver acesso ao System.linq, poderá usar o método de extensão útil Concat Para objetos ienumeráveis, como matrizes. Isso permitirá que você estenda uma matriz:
int[] result = new int[] { 1, 2 };
int[] extend = new int[] { 3, 4 };
result = result.Concat(extend).ToArray();
foreach (int i in result)
{
Console.WriteLine(i.ToString());
}
Resultado:
1
2
3
4