I have an array List as follows;
ArrayList myArrayList = new ArrayList();
for (int i = 0; i <= 1000; i++)
{
myArrayList.Add(i.ToString());
}
Then I am using IEnumerator and trying to pass the value to a function.
IEnumerator eee = myArrayList.GetEnumerator();
Now calling the function.
iteratefrom5to10(eee); //The error shown here is some invalid arguments.
static void iteratefrom5to10(IEnumerator<int> ien)
{
while (ien.MoveNext())
{
MessageBox.Show(ien.Current.ToString());
}
}
The above approach has worked with List. But not with ArrayList. What is wrong?
Stop using ArrayList - there are very few cases where you'd want to use it.
Since you're working with a list of integers, just use List<int> instead - no need to convert all the values to string and back :)
Finally, why are you using GetEnumerator anyway? Change the argument to IEnumerable<int> and the while to a foreach:
var list = new List<int>();
for (var i = 0; i <= 1000; i++)
{
list.Add(i);
}
static void iteratefrom5to10(IEnumerable<int> ien)
{
foreach (var value in ien)
{
MessageBox.Show(value.ToString());
}
}
IEnumerables are very easy to work with. For example, as your method's name suggests you want to iterate from 5 to 10, the same can be done with a simple list.Skip(4).Take(6).
You can do:
myArrayList.ToArray().AsEnumerable();
You need to cast myArrayList to IEnumerable<int> like this:
IEnumerator<int> eee = myArrayList.Cast<int>().GetEnumerator();
Please note that you are adding strings to the ArrayList. You should be adding integers instead like this:
ArrayList myArrayList = new ArrayList();
for (int i = 0; i <= 1000; i++)
{
myArrayList.Add(i);
}
Related
I have a class like this:
class MyClass { public object[] Values; }
Somewhere else I'm using it:
MyClass myInstance = new MyClass() {Values = new object[]{"S", 5, true}};
List<Func<MyClass, object>> maps = new List<Func<MyClass, object>>();
for (int i = 0; i < myInstance.Values.Length ; i++)
{
maps.Add(obj => obj.Values[i]);
}
var result = maps[0](myInstance); //Exception: Index outside the bounds of the array
I thought it will returns S, but it throw exception. Any idea what is going on?
To see what's going on, change your lambda to maps.Add(obj => i);.
With that change result will be 3, and that's why you're getting IndexOutOfBoundException exception: you're trying to get myInstance[3] which does not exist.
To make it work, add local int variable within your loop and use that one as index instead of loop counter i:
for (int i = 0; i < myInstance.Values.Length; i++)
{
int j = i;
maps.Add(obj => obj.Values[j]);
}
I am creating an application in window application using c#. I have a string array,and its value will be updated in each timer tick event. later on ,i have to convert this array into object array. I know, if we are modifying string many times,it can be time consuming to create new string objects.so i want to use stringBuilder.
let say, in timer tick event:
for (int i = 0; i < 10; i++)
{
n[i] = i.ToString();
}
where n is the string array and i want to use stringbuilder instead of array.
is it possible? how do i do this? how do i convert stringBuilder type to object type?
You do not need a StringBuilder here. A StringBuilder is only called for when processing (usually: concatenating) a single string many times. You have many small and unrelated strings.
What you probably want is to replace the array string[] with a List<string>.
You can keep your array of strings and use a StringBuilder in the loop.
var myValues = new String[100];
void tick() {
var sb = new StringBuilder();
for (int i = 0; i < 10; i++){
sb.append(i.ToString());
}
myValues.add(sb.ToString());
}
This adds all values in the range of 0 to 10 to one string. I don't know why you'd need this, so if you want to do something different you should clarify.
You can do something like this
StringBuilder obj=new StringBuilder();
for (int i = 0; i < 10; i++)
{
obj.append(i.ToString());
}
Here is another approach that does not need to use an array or StringBuilder and which should be efficient enough if the sequence is not too large:
string nums = String.Join("", Enumerable.Range(0, 10));
However, string.Join is really efficient if the input is already an array. In this case it might really be more efficient to use a StringBuilder:
string nums = Enumerable.Range(0, 10)
.Aggregate(new StringBuilder(), (a, b) => a.Append(b))
.ToString();
I would suggest you to use code something like :
class Program
{
static void Main(string[] args)
{
var dic = new Dictionary<int, StringBuilder>();
//Initialize dictionary
for (int i = 0; i < 10; i++)
{
dic.Add(i, new StringBuilder());
}
TimerElapsed(dic);
TimerElapsed(dic);
Process(dic.Values.ToArray());
}
public static void Process(object[] objects)
{
//Do your processing
}
public static void TimerElapsed(IDictionary<int, StringBuilder> dic)
{
for (int i = 0; i < 10; i++)
{
dic[i].Append(i.ToString());
}
}
}
Such code will give you benefits of collection and flexibility (for eg: you could convert to array easily)
I have list of structure. I want to modify a particular data from the structure.
And the structure is at the particular index location of the List.
I want to do something like this:
struct sample
{
int a;
string name;
}
List<sample> list = new List<sample>();
for(int i=0; i < list.Count; i++)
{
list[i].a = someotherlist[i].data;
}
The problem is that the list indexer creates a copy of the struct, i.e. it is really:
for(int i=0; i < list.Count; i++)
{
var completelyIsolatedClone = list[i];
completelyIsolatedClone.a = someotherlist[i].data;
}
The compiler is preventing you making an obvious mistake. The code you have uses the get, mutates a separate copy of the data, but never puts it back - so your change doesn't do anything useful. Note that the Mono folks think it would be nice if it worked your way, though: http://tirania.org/blog/archive/2012/Apr-11.html
Note that an array works differently; with an array you are touching the struct in place, so the following would work fine:
for(int i=0; i < list.Count; i++)
{
someArray[i].a = someotherlist[i].data;
}
Another approach is to copy the data out (the get accessor), mutate it, and put it back:
for(int i=0; i < list.Count; i++)
{
var completelyIsolatedClone = list[i];
completelyIsolatedClone.a = someotherlist[i].data;
list[i] = completelyIsolatedClone;
}
or better, acoid mutable structs completely, perhaps with a method that applies the change to a new copy:
for(int i=0; i < list.Count; i++)
{
list[i] = list[i].SetA(someotherlist[i].data);
}
where SetA creates a new struct, like DateTime.AddDays etc, i.e.
public SomeType SetA(int a) {
return new SomeType(this.X, this.Y, a, this.Z);
}
The reason you can't do it is because Sample is a struct, if you change it to a class then you can modify it. Structures are passed by value, that is, when a structure is returned by a method, a copy of the structure is returned, not the orginal structure. So when list[i].a = someotherlist[i].data; is run, you are actually modifying the copy and the orginal structure is not being changed. The compilers prevents you from doing this as it is probably not what you had intended.
You may look at this thread Why couldnot I modify the value of item from Generic Collections) ?
I just modified my code as bellow and it works fine for me
public struct test
{
public int data;
public string name;
public int port_index;
}
static void Main(string[] args)
{
List<test> look_up = new List<test>();
test obj;
obj.data = 1;
obj.port_index = 0;
obj.name = "aaaa";
look_up.Add(obj);
test obj1;
obj1.data=3;
obj1.port_index=1;
obj1.name="sssss";
look_up.Add(obj1);
for(int i=0;i<look_up.Count;i++)
{
if (i == 1)
{
test temp = look_up[i];
temp.data = 5;
look_up[i] = temp;
}
}
}
I would like to programmatically add or remove some elements to a string array in C#, but still keeping the items I had before, a bit like the VB function ReDim Preserve.
The obvious suggestion would be to use a List<string> instead, which you will have already read from the other answers. This is definitely the best way in a real development scenario.
Of course, I want to make things more interesting (my day that is), so I will answer your question directly.
Here are a couple of functions that will Add and Remove elements from a string[]...
string[] Add(string[] array, string newValue){
int newLength = array.Length + 1;
string[] result = new string[newLength];
for(int i = 0; i < array.Length; i++)
result[i] = array[i];
result[newLength -1] = newValue;
return result;
}
string[] RemoveAt(string[] array, int index){
int newLength = array.Length - 1;
if(newLength < 1)
{
return array;//probably want to do some better logic for removing the last element
}
//this would also be a good time to check for "index out of bounds" and throw an exception or handle some other way
string[] result = new string[newLength];
int newCounter = 0;
for(int i = 0; i < array.Length; i++)
{
if(i == index)//it is assumed at this point i will match index once only
{
continue;
}
result[newCounter] = array[i];
newCounter++;
}
return result;
}
If you really won't (or can't) use a generic collection instead of your array, Array.Resize is c#'s version of redim preserve:
var oldA = new [] {1,2,3,4};
Array.Resize(ref oldA,10);
foreach(var i in oldA) Console.WriteLine(i); //1 2 3 4 0 0 0 0 0 0
Don't use an array - use a generic List<T> which allows you to add items dynamically.
If this is not an option, you can use Array.Copy or Array.CopyTo to copy the array into a larger array.
Since arrays implement IEnumerable<T> you can use Concat:
string[] strArr = { "foo", "bar" };
strArr = strArr.Concat(new string[] { "something", "new" });
Or what would be more appropriate would be to use a collection type that supports inline manipulation.
Use List<string> instead of string[].
List allows you to add and remove items with good performance.
What's abaut this one:
List<int> tmpList = intArry.ToList();
tmpList.Add(anyInt);
intArry = tmpList.ToArray();
One liner:
string[] items = new string[] { "a", "b" };
// this adds "c" to the string array:
items = new List<string>(items) { "c" }.ToArray();
You should take a look at the List object. Lists tend to be better at changing dynamically like you want. Arrays not so much...
You can use a generic collection, like List<>
List<string> list = new List<string>();
// add
list.Add("element");
// remove
list.Remove("element");
You can use this snippet:
static void Main(string[] args)
{
Console.WriteLine("Enter number:");
int fnum = 0;
bool chek = Int32.TryParse(Console.ReadLine(),out fnum);
Console.WriteLine("Enter number:");
int snum = 0;
chek = Int32.TryParse(Console.ReadLine(),out snum);
Console.WriteLine("Enter number:");
int thnum = 0;
chek = Int32.TryParse(Console.ReadLine(),out thnum);
int[] arr = AddToArr(fnum,snum,thnum);
IOrderedEnumerable<int> oarr = arr.OrderBy(delegate(int s)
{
return s;
});
Console.WriteLine("Here your result:");
oarr.ToList().FindAll(delegate(int num) {
Console.WriteLine(num);
return num > 0;
});
}
public static int[] AddToArr(params int[] arr) {
return arr;
}
I hope this will help to you, just change the type
I am using the following code in C#. I am adding the values into the arraylist by using index. Now I want to read the values from the arraylist by using the index only. In the following example I am simply reading all the values from the arrylist but I want to read the values from the arrylist based on index( for e.g Customer_Details[i]) for each element at index i.
public struct Cust_Info
{
public String Client_Key;
public String Registration_Key;
public int Standard;
public Cust_Info(String C_Key, String Reg_Key, int Std)
{
Client_Key = C_Key;
Registration_Key = Reg_Key;
Standard = Std;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ArrayList Customer_Details = new ArrayList();
for (int i = 0; i < 1; i++)
{
Customer_Details.Insert(i, new Cust_Info("A", "B", 1));
}
//for (int i = 0; i < 1; i++)
//{
Customer_Details.Insert(1, new Cust_Info("C", "D", 2));
for (int i = 0; i < 1; i++)
{
ArrayList obj=new ArrayList();
//((ArrayListOFStructures.Form1.Cust_Info)((new System.Collections.ArrayList.ArrayListDebugView(Customer_Details)).Items[0])).Client_Key
//obj = (ArrayList)Customer_Details[i];
foreach (Cust_Info temp in Customer_Details)
{
//comboBox1.Items.Add(Customer_Details[0].ToString());
comboBox1.Items.Add(temp.Client_Key);
comboBox1.Items.Add(temp.Registration_Key);
comboBox1.Items.Add(temp.Standard);
}
}
}
In the above code i want to make the use the structure only. How can I read the values from the arrylist based on index. Can you please provide me any code or link through which I can resolve the above issue ?
I'm confused; you can get an item out of an ArrayList by index simply by:
Cust_Info cust = (CustInfo)theList[index];
However, ArrayList is pretty rare in anything >= .NET 2.0, a List<Cust_Info> would make this much easier. Also, Cust_Info looks to me very much like it should be a class (it is very rare to write a struct in .NET, and usually to denote "values" - a customer isn't a "value"). And public fields are also very much discouraged.
Note that currently you are (because it is a struct) actually copying the Cust_Info whenever you fetch it from (or place it in) the list; that isn't necessarily what you intend...
You can try something like
ArrayList arr = new ArrayList();
for (int iIndex = 0; iIndex < arr.Count; iIndex++)
{
object o = arr[iIndex];
}
But I would rather go with
List Class and List.Count Property
for(int i=0; i<Customer_Details.Count/*or.Length*/; i++)
Customer_Details[i] = something;