How do I add a new item from a TextBox and Button on a Windows Form at the end of an ArrayList which references a class?
private product[] value = new product[4];
value[1] = new product("One",5)
value[2] = new product("Two",3)
value[3] = new product("Three",8)
Workflow
Enter new products details into textbox1, textbox2, textbox3
When I click Add the new product gets added to the array:
value[1] = new product("One",5)
value[2] = new product("Two",3)
value[3] = new product("Three",8)
value[4] = new product("Four",2)
What is the code for doing this?
Arrays are fixed size, which means you can't add more elements than the number allocated at creation time, if you need a auto sizing collection you could use List<T> or an ArrayList
Example:
// using collection initializers to add two products at creation time
List<Product> products = new List<Product>{new Product("One",5), new Product("Two",3) };
// then add more elements as needed
products.Add(new Product("Three",8));
Use List as other people mentioned.
If you are set on arrays, use
Array.Resize<Product>(ref product, your new size);
If you're only going to be adding a couple of products (over the lifetime of your array) just do something like
Array.Resize<Product>(ref product, product.Length + 1);
If you are going to be adding a lot of products, you might want to do something similar to what List does - like this:
Array.Resize<Product>(ref product, product.Length * 2);
I think you need a List<product> collection, looking at your code. Then just call the Add() method on it
You can't add items to an array, you would have to create a new array that is larger and copy the items to it. There is a method for that, which is somewhat misleadingly named Resize as it doesn't actually resize the array:
Array.Resize<product>(ref value, 5);
If you want to add items to a collection, you should use a List instead:
private List<product> value = new List<product>();
value.Add(new product("One",5));
value.Add(new product("Two",3));
value.Add(new product("Three",8));
value.Add(new product("Four",2));
Edit:
If you want to resize the array, you might want to increase the size instead of resizing it to a specific value:
int index = value.Length;
Array.Resize<product>(ref value, index + 1);
value[index] = ...
Arrays are zero indexed, so an array initialized to a size of 4 could only be accessed up to index 3...
If you wanted the array to grow, then you'd have to either initialize the array at least as large as you wanted to be able to grow to, or else you'd have to create a new array with the new larger size and copy the old array over; not very efficient.
In this case, you'd do better to use a collection like a list, rather than an array, so that the size can dynamically increase.
You should probably also take a look at Array versus List: When to use which?
Array.Resize is not an efficient method. It creates a new array with the new size then copy old array values to the new array and then replaces the old array with the new array.
As you can see this is not a very efficient way of appending an item.
Unless it is a requirement that you have no control on use a List instead of array or create an array with maximum expected dimension from the beginning.
For more explanation consider this example:
You created an array that can hold million items and fill it with objects.
You want to add the million and one object to the array.
You use Array.Resize method to change array size to 1000001.
When the method tries to create a new array of 1000001 items and copy the items from old array to new array you may get an out of memory error because you are trying to have TWO arrays of a million (holding 2 millions objects) in memory at the same time while all the items that you need are one million +1.
Although consider the time and resources lost in creating, copying and replacing.
Related
Needed to store many varbiables and at first went with an array, but I had errors when I tried to resize the amount of positions in an array with a separate variabe. Looked online and people said, better use a List.
I have but very confusing to use. Trying to use it logically but I'm just not getting it.
So I set up my list:
public List<int> TESTValues = new List<int>(10);
And to me logically, there should be a list on 10 positions but there isn't, it's empty. Only does it add a variable if I use: TESTValues.Add(1); which only adds 1 new variable in the next available position which is 1 when it should be position 11 right?
Let's say I would somehow get a list of 10 variables, how would I then reference a variable in position 8 of the list, even update it? I tried to use something like: TESTValues.IndexOf(8) = 40; sadly that does not work.
Anyone have a good understanding of these Lists and how I could get to use them? Explain them? Was expecting a List to be simpley than an Array, seems the other way round right now.
Capacity != Size (Count)
Gets or sets the total number of elements the internal data structure can hold without resizing.
The initial capacity given to the constructor has only one purpose: Immediate allocation.
Usually by default a List<T> starts with an initial capacity of 4. Under the hood it simply stores the values in an array.
Then every time you add elements and the new size would exceed the capacity then the underlying array is copied into a new array with double of the original size (= capacity of the list).
The "size" (= Count of the list) only grows by adding elements!
Gets the number of elements contained in the List<T>.
Now the only way to initialize a list with already 10 elements is by using another collection like e.g.
var yourList = new List<int>(new int[10]);
of course this requires the allocation of an array => work for the GC but if you do this only once probably not very problematic.
or using Linq you could also do
using System.Linq;
...
var yourList = Enumerable.Repeat(0, 10).ToList();
Why do I need to use the Add() to add elements to a List. Why can't I use indexing and do it. When I traverse the elements through the List I do it using the help of indexes.
int head = -1;
List<char> arr = new List<char>();
public void push(char s)
{
++head;
arr[head] = s;//throws runtime error.
arr.Add(s);
}
It doesn't throw any error during compile time. But throws an error at runtime stating IndexOutOfRangeException.
++head;
arr[head] = s;
This attempts to set element 1 of the list to s, but there is no element 1 yet because you've not added anything, or set the length of the list.
When you create an array, you define a length, so each item has a memory address that can be assigned to.
Lists are useful when you don't know how many items you're going to have, or what their index is going to be.
Arrays are fixed sizes. Once you allocate them, you can not add or remove "slots" from it. So if you need it to be bigger, you need to:
Detect that you need a bigger array.
Allocate a new, bigger array
copy all existing values to teh new, bigger array
start using the bigger array from now on everywhere
All that Lists do is automate that precise process. It will automatically detect that it needs to increase during Add() and then do step 2-4 automagically. It is even responsible to pick the initial size and by how much to grow it (to avoid having to grow to often.
They could in theory jsut react to List[11000] by growing the size to 11000. But chances are very big, that this value is a huge mistake. And preventing the Progarmmer from doing huge mistakes is what half the classes and compiler rules (like strong typisation) are there for. So they force you to use Add() so such a mistake can not happen.
Actually calling myArray[2] does not add the element, but just assigns the object to the specified index within the array. If the array´s size is less you´d get an IndexOutOfBoundsException, as in a list<T> also. So also in case of an array using the indexer assumes you actually have that many elements:
var array = new int[3];
array[5] = 4; // bang
This is because arrays have a fixed size which you can´t change. If you assign an object to an index greater the arrays size you get the exat same exception as for a List<T> also, there´s no difference here.
The only real difference here is that when using new array[3] you have an array of size 3 with indices up to 2 and you can call array[2]. However this would just return the default-value - in case of int this is zero. When using new List<int>(3) in contrast you don´t have actually three elements. In fact the list has no items at all and calling list[2] throws the exception. The parameter to a list is just the capacity, which is a parameter for the runtime to indicate when the underlying array of a list should be resized - an ability your array does not even have.
A list is an array wrapper, where the internal array size is managed by its methods. The constructor that takes a capacity simply creates an array of that size internally, but the count property (which reflects the count elements that has been added) will be zero. So in essence, zero slots in the array has been assigned a value.
The size of an array is managed by you the programmer. That is why you have to call static methods like System.Array.Resize (notice that the array argument is ref), if you want to change an array yourself. That method allocates a new chunk of memory for the new size.
So to sum up, the list essentially manages an array for you, and as such, the tradeoff is that you can only access as many array-like slots as has been added to it.
var mylist1 = new List<float>(5);
var mylist2 = new List<float>(new float[5]);
mylist1 gets 5 as a capacity. mylist2 gets 5 too. What is the difference between these two and which one should I use?
The first declaration creates a list with an underlying array with a size of 5.
The second declaration copies data from the passed array to the underlying array in the list.
So the second declaration needs to:
Create an empty array
Copy the values in that array to another array
Since it's also harder to read (what's the point of passing an empty array to a list constructor?), there really isn't any reason at all to use the second instead of the first.
The reason the overload is there is to allow you to prefill the list with values from another array or enumerable. For example:
var list = new List<int>(Enumerable.Range(1, 100));
(though of course, even then you'd usually use Enumerable.Range(1, 100).ToList() instead :))
The first create a List having capacity 5, but empty.i.e, if you access myList1[3] you get an error.
The second create a List of float containing already 5 elements. each element will have value 0.0, i.e the default value for a float
I have a char array in C#.
var arr = new char[3] { 'a','b','c' };
How do I add spaces to the end of it without creating a new array?
result: arr = { 'a', 'b', 'c', ' ', ' ', ' ' };
This might sound similar to VB.NET's ReDim. But I'm not sure that is what I want either.
I want to preserve the elements inside of it and not instantiate a new array behind the scenes.
Is this only possible with Generic Collections and ArrayList?
Thanks
No, this is not possible using an array, generic or otherwise.. AFAIK, there is no way to dynamically resize an array. Use a List instead.
As Martin pointed out in the comments, even the List class uses an array in its internal implementation. If you want to truly be able to dynamically resize a data structure without reinitializing it, you must implement your own version of a linked list.
System.Collections.Generic contains a class called LinkedList that represents a doubly-linked list (meaning that each node has a reference to both the next and the previous node), but I'm not sure if its internal implementation uses an array..
Unfortunately, arrays are pre-fixed by design. This is important because it will reserve the necessary amout of memory at the heap.
So, to answer your requirement about not creating a new one: it won't be possible.
There is, however, a work-around. Look the following method:
Array.Resize(ref myArr, myArr.Length + 5);
It works as described at the source:
This method allocates a new array with the specified size, copies
elements from the old array to the new one, and then replaces the old
array with the new one.
If array is null, this method creates a new array with the specified
size.
If newSize is greater than the Length of the old array, a new array is
allocated and all the elements are copied from the old array to the
new one. If newSize is less than the Length of the old array, a new
array is allocated and elements are copied from the old array to the
new one until the new one is filled; the rest of the elements in the
old array are ignored. If newSize is equal to the Length of the old
array, this method does nothing.
This method is an O(n) operation, where n is newSize.
This means that myArr will be updated to reference the new array. However, if there is another reference to the original array, this won't be updated (it will keep referencing the older version).
Source: MSDN
I've just started learning C# and in the introduction to arrays they showed how to establish a variable as an array but is seems that one must specify the length of the array at assignment, so what if I don't know the length of the array?
Arrays must be assigned a length. To allow for any number of elements, use the List class.
For example:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
Use List<> to build up an 'array' of unknown length.
Use List<>.ToArray() to return a real array, and not a List.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
A little background information:
As said, if you want to have a dynamic collection of things, use a List<T>. Internally, a List uses an array for storage too. That array has a fixed size just like any other array. Once an array is declared as having a size, it doesn't change. When you add an item to a List, it's added to the array. Initially, the List starts out with an array that I believe has a length of 16. When you try to add the 17th item to the List, what happens is that a new array is allocated, that's (I think) twice the size of the old one, so 32 items. Then the content of the old array is copied into the new array. So while a List may appear dynamic to the outside observer, internally it has to comply to the rules as well.
And as you might have guessed, the copying and allocation of the arrays isn't free so one should aim to have as few of those as possible and to do that you can specify (in the constructor of List) an initial size of the array, which in a perfect scenario is just big enough to hold everything you want. However, this is micro-optimization and it's unlikely it will ever matter to you, but it's always nice to know what you're actually doing.
You can create an array with the size set to a variable, i.e.
int size = 50;
string[] words = new string[size]; // contains 50 strings
However, that size can't change later on, if you decide you need 100 words. If you need the size to be really dynamic, you'll need to use a different sort of data structure. Try List.
Use an ArrayList if in .NET 1.x, or a List<yourtype> if in .NET 2.0 or 3.x.
Search for them in System.Collections and System.Collections.Generics.
You might also want to look into Dictionarys if your data is unique, This will give you two columns to work with.
User name , Total bill
it gives you a lot of built in tools to search and update just the value.
var yummy = new List<string>();
while(person.FeelsHappy()) {
yummy.Add(person.GetNewFavoriteFood());
}
Console.WriteLine("Sweet! I have a list of size {0}.", list.Count);
Console.WriteLine("I didn't even need to know how big to make it " +
"until I finished making it!");
try a generic list instead of array
In a nutshell, please use Collections and Generics.
It's a must for any C# developer, it's worth spending time to learn :)
As detailed above, the generic List<> is the best way of doing it.
If you're stuck in .NET 1.*, then you will have to use the ArrayList class instead. This does not have compile-time type checking and you also have to add casting - messy.
Successive versions have also implemented various variations - including thread safe variants.
If you really need to use an array instead of a list, then you can create an array whose size is calculated at run time like so...
e.g i want a two dimensional array of size n by n. n will be gotten at run time from the user
int n = 0;
bool isInteger = int.TryParse(Console.ReadLine(), out n);
var x = new int[n,n];