Declaring dynamic variables inside for loop (C#) - c#

I have a task when I type for example 2 in the console then I am supposed to parse the next two lines of strings. I am giving you a clear example:
2
J 1 1 1 1
B 0 0 0 1
So when i do a for loop like this and when I console write it only shows me the 2nd basilisk(B 0 0 0 1):
string basilisk;
int basilisk1D = 0;
int basilisk2D = 0;
int basilisk3D = 0;
int basilisk4D = 0;
string basiliskName = string.Empty;
for (int i = 0; i < numberOfBasilisks; i++)
{
basilisk = Console.ReadLine();
var splittedBasilisk = basilisk.Split(' ');
basiliskName = splittedBasilisk[0];
basilisk1D = int.Parse(splittedBasilisk[1]);
basilisk2D = int.Parse(splittedBasilisk[2]);
basilisk3D = int.Parse(splittedBasilisk[3]);
basilisk4D = int.Parse(splittedBasilisk[4]);
}
It erases me the first line and only put the data of the second basilisk so can I put in the for loop i in the name of the variables to make them unique for each of basilisk or there is a better solution?

You cannot put eight integers and two strings into four int variables and one string variable. You need store the results in some sort of a collection.
First, create a class to store row data:
class Basilisk {
public string Name {get;set;}
public string Num1 {get;set;}
public string Num2 {get;set;}
public string Num3 {get;set;}
public string Num4 {get;set;}
}
Since you know right away how many rows you want, you can use arrays:
var basilisks = new Basilisk[numberOfBasilisks];
for (int i = 0; i < numberOfBasilisks; i++) {
basilisks[i] = new Basilisk();
var str = Console.ReadLine();
var splittedBasilisk = str.Split(' ');
basilisks[i].Name = splittedBasilisk[0];
basilisks[i].Num1 = int.Parse(splittedBasilisk[1]);
basilisks[i].Num2 = int.Parse(splittedBasilisk[2]);
basilisks[i].Num3 = int.Parse(splittedBasilisk[3]);
basilisks[i].Num4 = int.Parse(splittedBasilisk[4]);
}
You can also use collections, depending on whether or not you have progressed to using lists in your coursework.

Related

How to declare and initialize multiple variables (with different names) within a for loop without using arrays?

I'm trying to perform the job that an array is supposed to do, but without actually using one. I was wondering if this was possible, and if it is, how?
I have to initialize different variables, for example:
int value1 = 0;
int value2 = 0;
int value3 = 0;
int valueN = 0;
I want to receive a value from the user that determinate what is the for loop going to last.
Example: User --> 4
Then I can declare 4 variables and work with them.
for (i = 1; i <= 4; i++) {
Console.Write("Insert a number: ");
int value(i) = int.Parse(Console.ReadLine());
}
I expect to have 4 variables called equally, but with the only one difference that each one has a different number added at the end of the name.
// value1 = 0;
// value2 = 0;
// value3 = 0;
// valueN = 0;
You cannot create dynamically named variables in C# (and I am with those who are wondering why you want to do that). If you don't want to use an array, consider a Dictionary -- it would perform better than an array in some circumstances.
Dictionary<string, int> values = new Dictionary<string, int>();
for (int i = 1; i <= 4; i++)
{
values.Add("value" + i, 0);
}
value["value1"]; //retrieve from dictionary

I need to find the max value in a array with C#

I have a multidimensional array with five countries and some medals. The last column is the total and i need to return the country with most medals. My code is "working" as long as there are no two countries with the same number of medals and those being the max number.
Problably i just don't have enough experience with arrays, but how can i return more than one contry, if i need?
string [,] medals = new string[5, 5];
Random rdn = new Random();
medals[0, 0] = "Brazil";
medals[1, 0] = "USA";
medals[2, 0] = "Russia";
medals[3, 0] = "France";
medals[4, 0] = "Egypt";
for (int i = 0; i < medals.GetLength(0); i++)
for (int j = 1; j < medals.GetLength(1); j++)
{
//This fills the gold, silver and copper medals
if (j < medals.GetLength(1)-1)
medals[i, j] = rdn.Next(1, 6).ToString();
else
//This fills the total medals
medals[i, j] = (int.Parse(medals[i, 1]) + int.Parse(medals[i,2]) + int.Parse(medals[i,3])).ToString();
}
//The first index stores the max number so far and the second stores the name of the country
string [] winner = { "0", "0" };
for (int i = 0; i < medals.GetLength(0); i++)
{
if (int.Parse(medals[i,4]) > int.Parse(winner[0]))
{
winner[0] = medals[i, 4];
winner[1] = medals[i, 0];
}
}
You could use a list to store the winners.
var listWinners = new List<KeyValuePair<string,string>>();
for (int i = 0; i < medals.GetLength(0); i++)
{
if ((listWinners.Count() == 0)||(int.Parse(medals[i,4]) > int.Parse(listWinners.First().Value)))
{
listWinners.Clear();
listWinners.Add(new KeyValuePair<string,string>(medals[i,0],medals[i,4]));
}
else if (int.Parse(medals[i,4]) == int.Parse(listWinners.First().Value))
{
listWinners.Add(new KeyValuePair<string,string>(medals[i,0],medals[i,4]));
}
}
But I would like reiterate what has been said in the comments, it would be much better if you could use a List of Object rather than multi-dimentional array. It would increase your readability of code and make things much simpler.
A dictionary would be a much easier starting place. You could then just sort based on the values in the dict and use a simple loop to check for duplicate values.
There are a lot of things I would do differently than you, but that's besides the point (see note at the end). Your issue is how to deal with the situation where you have multiple countries with equal and max number of medals.
How to return multiple countries?
Well, that's easy: imagine you return the winner from the below function:
string[] GetWinner() {
// your code
return new[] { "20", "USA" };
}
Then there is no change in the data type, simply add another country to the array and the calling code should check how many you have
string[] GetWinner() {
// your code
return new[] { "20", "USA", "CAN" };
}
Now if you have a problem as to how to create an array whose size is unknown while creating it, then the usual solution is to use List<>, which in this case will act as a re-sizable array for you.
The final code would look something like below
static string[] GetWinner(string[,] medals) {
int rows = medals.GetLength(0);
var winners = new List<string>();
int maxMedals = 0;
for (var i = 0; i < rows; i++) {
var n = int.Parse(medals[i, 4]);
maxMedals = n > maxMedals ? n : maxMedals;
}
for (var i = 0; i < rows; i++) {
var n = int.Parse(medals[i, 4]);
if (n == maxMedals)
winners.Add(medals[i, 0]);
}
winners.Insert(0, maxMedals.ToString());
return winners.ToArray();
}
Now, I would advise you to use a better data structure to store your medals. But since I don't know the full situation, I would guess, something like below is reasonable. Instead of using named types, you can use ValueTuple - to make the code concise, if the code related to these objects are restricted to a small area of a the code file. This should avoid allocating big chunk of memory associated with 2D arrays, and also storing of int in string.
public class CountryMedalTally {
public string Country { get; set; }
public string[] Medals { get; set; }
public int MedalCount { get; set; }
}
public class Winner {
public List<string> Country { get; set; }
public int MedalCount { get; set; }
}
List<CountryMedalTally> AllMedals;

C# Array, String, error

int i;
int [,] Prices = new int [2, 7]{{1,2,3,4,5,6,7},{700,600,500,400,300,200,100}};
string[,] City = new string [2,1]{{"A"},{"B"}};
bool found = false;
for (i = 0; i <= City.Length -1; i++)
// for (y = 0; y <= City.Length - 1; y++)
{
if (LstDestinationCity.Text == City[i]) <<-- i get error here
{
im planing to do a program that if i select A city i get first row if B city i get 2 row
I think that's because City[i] "don't contain anything" you should check City[i,0]
if (LstDestinationCity.Text == City[i,0])// this should access the first element which is the text you are looking for
I would rather do it as
if (LstDestinationCity.Text == City[i,i])
{
// ...
}
Your City variable does not need to be a two dimensional array. If you change it to a one dimensional array you can access the values with one index instead of 2.
string[] City = new string [2]{"A","B"};

Adding numbers to a string?

I have strings that look like "01", "02". Is there an easy way that I can change the string into a number, add 1 and then change it back to a string so that these strings now look like "02", "03" etc. I'm not really good at C# as I just started and I have not had to get values before.
To get from a string to an integer, you can youse int.Parse():
int i = int.Parse("07");
To get back into a string with a specific format you can use string.Format():
strings = string.Format("{0:00}",7);
The latter should give "07" if I understand http://www.csharp-examples.net/string-format-int/ correctly.
You can convert the string into a number using Convert.ToInt32(), add 1, and use ToString() to convert it back.
int number = Convert.ToInt32(originalString);
number += 1;
string newString = number.ToString();
Parse the integer
int i = int.Parse("07");
add to your integer
i = i + 1;
make a new string variable and assign it to the string value of that integer
string newstring = i.ToString();
AddStringAndInt(string strNumber, int intNumber)
{
//TODO: Add error handling here
return string.Format("{0:00}", (int.TryParse(strNumber) + intNumber));
}
static string StringsADD(string s1, string s2)
{
int l1 = s1.Count();
int l2 = s2.Count();
int[] l3 = { l1, l2 };
int minlength = l3.Min();
int maxlength = l3.Max();
int komsu = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < maxlength; i++)
{
Int32 e1 = Convert.ToInt32(s1.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 e2 = Convert.ToInt32(s2.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 sum = e1 + e2 + komsu;
if (sum >= 10)
{
sb.Append(sum - 10);
komsu = 1;
}
else
{
sb.Append(sum);
komsu = 0;
}
if (i == maxlength - 1 && komsu == 1)
{
sb.Append("1");
}
}
return new string(sb.ToString().Reverse().ToArray());
}
I needed to add huge numbers that are 1000 digit. The biggest number type in C# is double and it can only contain up to 39 digits. Here a code sample for adding very huge numbers treating them as strings.

loop though a array then if and then output result?

i have a little problem, in the code below (C#) it loops thought the arrays, it then check if the user_id has a user_post greater than 50, it then write the user_id, the expected outcome is
12
13
but the actual output is
12
12
12
whats wrong with the code? I tried a standard for loop but could not get it right?
int[] user_id = new int[64];
int[] group_id = new int[64];
int[] user_post = new int[64];
//user 55
user_id[0] = 10;
group_id[0] = 8;
user_post[0] = 4;
//user56
user_id[1] = 11;
group_id[1] = 2;
user_post[1] = 15;
//user57
user_id[2] = 12;
group_id[2] = 2;
user_post[2] = 55;
//user58
user_id[3] = 13;
group_id[3] = 2;
user_post[3] = 56;
foreach (int i in group_id)
{
if (group_id[i] == 2)
if (user_post[i] > 50)
Console.WriteLine(Convert.ToString(user_id[i]));
}
Console.WriteLine("Press any key too continue...");
Console.ReadLine();
// continue...
Because you have an if statement that only checks for 2
if (group_id[i] == 2)
where as "i" is not a counter instead the element from the foreach loop.
and items at 2 & 3rd position have 2 group id so it alway ends like this:
if (group_id[8] == 2) //false
if (group_id[2] == 2) //true
if (group_id[2] == 2) //true
Instead of that vague code you should have your loop as this:
for(int i = 0 ; i< 64 ; i++)
{
if (group_id[i] == 2)
{
if (user_post[i] > 50)
Console.WriteLine(Convert.ToString(user_id[i]));
}
}
in your foreach statement, i takes on the values stored in your group_id array - 8, 2, 2, 2
In your if and output statements, your are using this value as an index into the arrays
So, your if statements end up doing this:
if(group_id[8])...
if(group_id[2])...
if(group_id[2])...
if(group_id[2])...
You are only examining elements 8 and 2 in your arrays.
Use a for loop to iterate through the array indexes
The for syntax is as follows:
for (int i = 0; // incremental variable
i < 100; // determining a limit
++i) // increment the variable
While foreach works like this:
foreach (var element // the element itself, not an index
in
elementCollection) // iterating through the collection
You're looping around the wrong array with the for each statement. You should loop using the regular for statement instead like this:
for (int i = 0;i < user_post.Length; i++)
{
if (user_post[i] > 50 && group_id[i] == 2)
{
Console.WriteLine(Convert.ToString(user_id[i]));
}
}
foreach (int i in group_id)
is wrong, you must use:
for(int i = 0; i < group_id.Length; i++)
because with the former you're using the values in group_id as indexes of your arrays.
BTW, I'd suggest you to create a class e.g. Info like:
class Info
{
public int GroupId {get; set;};
public int UserId {get; set;};
public int PostId {get; set;}
}
this would allow you to create one array only (i.e. Info[]) and avoid possible errors due to different lenghts of the 3 arrays...

Categories