C# increase length of a string array [duplicate] - c#

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
how to inset a new array to my jagged array
i have a problem, where i dont know how i can make a string array variable in array length.
i have this code now below:
string[] p = new string[10];
int num = 0;
foreach (Product products in GetAllProducts())
{
//do something
p[num]= "some variable result"
num++
}
The problem is, that i dont know how many of "p" i will get, although i know it atleast will be less than 10.
but if i put it on 0, i will get an error when i start it, because it doesn't know the "p[num]"
So i am looking for some way to make "p" have a variable length.
anyone could help me out a bit? thanx
============Solved==========
List<string> p = new List<string>();
int num = 0;
foreach (Product products in GetAllProducts())
{
string s= null;
//do something ( create s out of multiple parts += s etc.)
p.add(s)
num++
}
thanx to solution poster

Use an List<string> instead of an array, if you do not know the number of items you will need to add.

Your array length cannot be modified after it has been instantiated. Use ArrayList or Generic Lists.

var p = new new List<string>(10);
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}

What does GetAllProducts() return? Does it have a count or a length?! You should call that first, save it in a variable, get the count/length and then declare your array!

There's two solution.
If you want to keep using array :
int num = 0;
var list = GetAllProducts();
string[] p = new string[list.Length]; // Or list.Count if this is a collection
foreach (Product products in list)
{
//do something
p[num] = "some variable result";
num++;
}
Otherwise you should use a List like this :
List<string> p = new List<string>();
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}

Use Array.Resize() method, which allows to resize it (by n number of indexes).
In my exmaple I will reize by 1 on each step of the way:
string[] array = new string[3]; //create array
for (int i = 0; i < 5; i++)
{
if (array.Length-1 < i) //checking for the available length
{
Array.Resize(ref array, array.Length + 1); //when to small, create a new index
}
array[i] = i.ToString(); //add an item to array[index] - of i
}

Because your code is using a foreach on the result from GetAllProducts, then GetAllProducts must be returning a IEnumerable collection. Probably the best solution would be to simply assign the result of GetAllProducts to such a collection. For example, perhaps it already returns a list of strings? So you can do:
List<string> strings = GetAllProducts();
There is no need to have a foreach loop to create an array when you already have a collection anyway being returned from GetAllProducts.
Or simply:
var strings = GetAllProducts();
to let the compiler work out the type of strings.
Most things you can do with an array you can also do with a List, and some more (such as adding items to the end of the List).
Perhaps you can post the signature of GetAllProducts (especially its return type) so we can better advise you?

I see many gave you the right answer which is the use of Lists. If you still need an array in the end, you can easily convert your list into an Array like this :
string[] tempArray = myList.ToArray();

Related

How to pass the elements in Array from a list to a List? c#

Pre-information
-User inputs data in console
-Save data in an Array of 2 elements[2]
-Save the Array with 2 elements in a LIST
*Now what i try to achieve is that the user can check if search is in the list regardless if its written in lower or upper case.
List<string[]>MyList = new List<string[]>();
var[] myArray = new [] { "A", "B" };
MyList.Add(myArray);
int y = 0;
Console.WriteLine("Inpu what you are Searching For: ");
string serchString = Console.ReadLine();
serchString = serchString.ToLower();
for (int i = 0; i < MyList.Count; i++)
{
List<object> oneTimeList = new List<object>();
oneTimeList.AddRange(myList[i]);
Console.WriteLine(oneTimeList);
if (MyList[i].Contains(serchString.ToLower()))
{
Console.WriteLine("Yes you have added this");
}
else if (!myList[i].Contains(serchString))
{
y += 1;
}
}
if (y == myList.Count)
{
Console.WriteLine("You Have not entered this Yet");
}
My logic(maybe not the best in the planet :P) says that i have to make a comparison of all the elements of the array in turn with the search the user made and if its true continue, And in order to make this i need first to get the information of the arrays of the list and convert them to a list and then convert them to lowercase.
Every thing goes fine until the part where i try to add the Arrays to the List and all i am adding are Arrays[].
Any Suggestion on how to approach this issue or how to pass the elements of an ARRAY that is inside of a LIST to a NEW LIST?
It sounds like to want to take an array of strings (assumed as you mention lower casing it), add them all to a list, lower-case them and then compare?
This being the case you don't need to do any of that. You can simply do:
var myArray = new [] { "A", "B", "C" }
var toCheck = "a";
//Use the IEnumerable<T>.Contains() Linq extension
if (myArray.Contains(toCheck, StringComparer.OrdinalIgnoreCase))
{
//...
}
If you really want to add them to a list I can't give you an example using your code, but to "pass elements of an array to a new list" you can do any of the following:
//List<T>(IEnumerable<string>) constructor
var newList = new List<string>(myListOfStrings);
//List<T>.AddRange(IEnumerable<string>)
var newList = new List<string>();
newList.AddRange(myListOfStrings);
//List<T>.Add(T) (adding items one at a time)
var newList = new List<string>();
newList.Add(myListOfStrings[index]);
It's worth noting here as well that any of the above references to myListOfStrings could be an array of strings (string[]) or a list of strings (List<string>) because they both implement IEnumerable<string> which is the type the above methods require (except for Add which wants a single item).
Here is the documentation for List that describes in details how to use each of the above (and all other other available methods...)

Setting the value of an index of a string array to that of an item within an Enumerable array by using a "foreach" statement.

Is this the best way to set each item of a string array to that of an Enumerable array? I came up with this approach on my own, I tried to use my google-foo but couldn't really come up with coherent sentences to describe what i'm trying to do here..
string[] adapterDesc = new string[] {};
int i = 0;
foreach(NetworkInterface adapter in adapters)
{
adapterDesc[i] = adapter.Description;
i++;
}
...
No, that code will fail with an IndexOutOfRange exception because you have declared an array of strings that could contain zero elements.
So when you try to set the first element it will crash.
Instead you could use a List where you can add elements dynamically
List<string> adapterDesc = new List<string>();
foreach(NetworkInterface adapter in adapters)
{
adapterDesc.Add(adapter.Description);
}
...
A List is more flexible than an array because you don't have to know before the size of the array and you could still use it like it was an array
for(int x = 0; x < adapterDesc; x++)
{
Console.WriteLine(adapterDesc[x]);
}
If you want to use Linq then you could even reduce your code to a single line with
string[] adapterDesc = NetworkInterface.GetAllNetworkInterfaces()
.Select(ni => ni.Description)
.ToArray();

Manipulating Values in Dictionary

So I have a dictionary whose index is an int, and whose value is a class that contains a list of doubles, the class is built like this:
public class MyClass
{
public List<double> MyList = new List<double>();
}
and the dictionary is built like this:
public static Dictionary<int, MyClass> MyDictionary = new Dictionary<int, MyClass>();
I populate the dictionary by reading a file in line by line, and adding the pieces of the file into a splitstring, of which there is a known number of parts (100), then adding the pieces of the string into the list, and finally into the dictionary. Here's what that looks like:
public void DictionaryFiller()
{
string LineFromFile;
string[] splitstring;
int LineNumber = 0;
StreamReader sr = sr.ReadLine();
while (!sr.EndOfStream)
{
LineFromFile = sr.ReadLine();
splitstring = LineFromFile.Split(',');
MyClass newClass = new MyClass();
for (int i = 1; i < 100; i++)
{
newClass.MyList.Add(Convert.ToDouble(splitstring[i]));
}
MyDictionary.Add(LineNumber, MyClass);
LineNumber++;
}
}
My question is this: is I were to then read another file and begin the DictionaryFiller method again, could I add terms to each item in the list for each value in the dictionary. What I mean by that is, say the file's 1st line started with 10,23,15,... Now, when I read in a second file, lets say its first line begins with 10,13,18,... what I'm looking to have happen is for the dictionary to have the first 3 doubles in its value-list (indexed at 0) to then become 20,36,33,...
Id like to be able to add terms for any number of files read in, and ultimately then take their average by going through the dictionary again (in a separate method) and dividing each term in the value-list by the number of files read in. Is this possible to do? Thanks for any advice you have, I'm a novice programmer and any help you have is appreciated.
Just Replace
newClass.MyList.Add(Convert.ToDouble(splitstring[i]))
with
newClass.MyList.Add(Convert.ToDouble(splitstring[i]) + MyDictionary[LineNumber].GetListOfDouble()[i])
and then replace
MyDictionary.add(Linenumber, Myclass)
with
MyDictionary[linenumber] = MyClass
Just makes sure that the MyDictionary[LineNumber] is not null before adding it :)
Something like this would work
If(MyDictionary[LineNumber] == null)
{
MyDictionnary.add(LIneNUmber, new List<double>());
}
If(MyDictionary[LineNUmber][i] == null)
{
return 0;
}
My solution does not care about list size and it done at reading time not afterward, which should be more efficient than traversing your Dictionary twice.
var current = MyDictionary[key];
for(int i = 0; i < current.MyList.Length; i++)
{
current.MyList[i] = current.MyList[i] + newData[i];
}
Given both lists have same length and type of data.
You can get the custom object by key of the dictionary and then use its list to do any operation. You need to keep track of how many files are read separately.

Deleting a specific item of an array [duplicate]

This question already has answers here:
Remove element of a regular array
(15 answers)
Closed 9 years ago.
string[] columns
I want to delete the item on an index specified by a variable of type int.
How do I do this ?
I tried
columns.RemoveAt(MY_INT_HERE);
But apparently this does not works.
Array is immutable class, you can't change it, all you can do is to re-create it:
List<String> list = columns.ToList(); // <- to List which is mutable
list.RemoveAt(MY_INT_HERE); // <- remove
string[] columns = list.ToArray(); // <- back to array
May be the best solution is to redesign your code: change immutable array into List<String>:
List<String> columns = ...
columns.RemoveAt(MY_INT_HERE);
If you don't want to use linq you can use this function :
public string[] RemoveAt(string[] stringArray, int index)
{
if (index < 0 || index >= stringArray.Length)
return stringArray;
var newArray = new string[stringArray.Length - 1];
int j = 0;
for (int i = 0; i < stringArray.Length; i++)
{
if(i == index)continue;
newArray[j] = stringArray[i];
j++;
}
return newArray;
}
You use it like that : columns = RemoveAt(columns, MY_INT_HERE)
You can also make it to an extension method.
You cannot delete items in an array, because the length of a C# array is fixed at the time when it is created, and cannot be changed after that.
You can null out the corresponding element to get rid of the string, or use LINQ to produce a new array, like this:
columns = columns.Take(MY_INT_HERE-1).Concat(columns.Skip(MY_INT_HERE)).ToArray();
You need to add using System.Linq at the top of your C# file in order for this to compile.
However, using a List<string> would be a better solution:
List<string> columns;
columns.RemoveAt(MY_INT_HERE);
Try one of the following (depending on what you need):
columns[MY_INT_HERE] = null;
columns[MY_INT_HERE] = string.Empty;
...otherwise you'll just have to create a new array which has a length of 1 less than your current array, and copy the values over.
If you want something more flexible, you might use a something like a List<string>, where you can use RemoveAt()
Arrays are faster for the computer to work with but slower for a programmer. You will have to find that value with a loop or some other means, then set that position to null. You will end up with an empty space in the array. You could reallocate the array etc etc...
What is easier to use for relatively small amounts of data is a List. You can do myList.RemoveAt(100); and it will work nicely.
You can not delete it.You can recreate the array or I advice you to use List<string> for the same.
List<string> columns = new List<string>();
columns.RemoveAt(1);
It will remove the 2nd element from your List<String> columns

How to get the size of arrays packed as value in a Dictionary<K,V> in C#?

I have a Dictionary<K,V> object already filled with data:
Dictionary<string, double[]> ltableData;
Every double[] has the same size (number of elements).
I do not know in advance neither any 'string' key nor the size of the 'double[]' values.
Now I have to make one cycle with a nested one as follows:
for(int i = 0; i< number_elements;i++)
{
foreach (var array in ltableData.Values)
{
ltempList.Add(array[i]);
//other instructions
}
}
How can I assign number_elements? I can of course use this solution:
var lrowCount;
foreach(var item in ltableData.Values)
{
lrowCount = item.Count();
}
that works but it is of course ugly both to see and execute. Is there any cleaner and more effective method to extract the count? Thanks
Francesco
var lrowCount = ltableData.Values.First().Length;
// or
var lrowCount = ltableData.First().Value.Length;
foreach (var array in ltableData.Values)
{
for (int i = 0; i < array.Length; i++)
{
//other instructions
}
}
or, even more readable,
foreach (var array in ltableData.Values)
{
foreach (var val in array)
{
//other instructions
}
}
You can take its length from any item:
int number_elements = ltableData.Values.Select(v => v.Length).FirstOrDefault();
Though I think if you have such structure then you should create a class for it which will have a Length on top level and which will also assert and guarantee that all inner items have the same length.
If you know that itableData does contain values you can do the following.
ltableData.Values.First().Count();
I'm not going to say this is much cleaner, but you could do
var number_elements = ltableData.Values.First().Count();
This is ONLY if you must need the length. Otherwise, a foreach loop would be just fine.
Now that you've clarified what you're doing as per the comments on your original post, it's clear that you actually want
using System.Linq;
var ltempList = ltableData.SelectMany(kvp => kvp.Value);
This will give an IEnumerable<double> containing all of the values from all different entries in the dictionary, aggregated together.
you can use this to get the total number of values
var number_elements = ltableData.Select(p => p.Value.Count()).Sum();

Categories

Resources