How to instantiate a list with a specific numbers of values without know the value? - c#

I'm using LiveChart of wpf, and I want instantiate a list of Decimal with 30 values (just as space as an array), actually I did:
public SeriesCollection MonthProfit {get;set;} = new SeriesCollection();
int i = 0;
MonthProfit[0].Values = new ChartValues<decimal>();
MonthProfit[0].Values[i] = 25;
but I get:
Index out of range
how can I define 30 values inside the index 0?

It looks to me like you could use the ChartValues constructor that accepts an IEnumerable<T>:
MonthProfit[0].Values = new ChartValues<decimal>(Enumerable.Repeat(0m, 30));

Related

Assigning a value to a variable which is stored in another variable

I am looking for some direction in this code.
What I have is 2 variables:
1) CalcTimeDown - a string variable in a for loop which takes various values which correspond to another string variable for each value in the for loop
Initial value is a string - "CalculationTimeDown". This gets suffixed by 000, 001, 002 and 003 and 004 giving me CalculationTimeDown000, CalculationTimeDown001, CalculationTimeDown002..etc
2) CalculationTimeDown000, CalculationTimeDown001, CalculationTimeDown002..etc are "id" in an XML Layout. And should get values of 00:00, 00:30, 01:00... etc.
What I am trying to do is:
Loop in the for loop from 0 to 4.
Set values to the variable CalcTimeDown to CalculationTimeDown000,
CalculationTimeDown001, ..... etc.
Load variable CalculationTimeDown000 with "00:00"
Load variable CalculationTimeDown001 with "00:30"
Load variable CalculationTimeDown002 with "01:00"
Load variable CalculationTimeDown003 with "00:30"
Load variable CalculationTimeDown004 with "02:00"
The Bold step above is what I am unable to accomplish - can someone guide me?
// Assemble the variable name
this.CalcTimeDownInitial = "CalculationTimeDown";
for (int i = 0; i <= 4; i++)
{
// Assemble the variable name
this.CalcTimeDown = this.CalcTimeDownInitial + i.ToString("000");
var TimeSlotVariable = new StringtoVariable(CalcTimeDown);
this.iSlot = (i) * 30;
//
// Get the time to be pumped
DateTime TimeSlotValue = DateTime.Now.AddMinutes(this.iSlot);
//
// CalcTimeDown contains the variable name where I want to pump the value of TimeSlotValue
// TimeSlotValue contains 00:00, 00:30, 01:00 etc.
//INCORRECT SYNTAX - HELP HERE PLEASE.
TimeSlotVariable = TimeSlotValue;
Thank you in advance.
Uttam
PS: I could not find an example using Reflection which I could adapt for my use in the example above - hence this posting.
-------Edit added to explain difference------
This edit to explain how my question is different from the possible duplicate:
That question was about Accessing the value - the value is already loaded in that case.
My question is about loading a value - loading the value is what I am trying to accomplish.
Could you please remove the vote down, if my explanation is reasonable? Thanks!
There's no point in creating variable names dynamically to store values in - if you can even get such a thing to work in C#. I've seen others try to do the same thing, but all they usually need is a collection.
Store each value in a List<T> where T is just the type of your data.
var timeSlotValues = new List<DateTime>();
for (int i = 0; i <= 4; i++)
{
timeSlotValues.Add(DateTime.Now.AddMinutes(i * 30));
}
I assume you'll eventually use this in a dropdown or something - you can just assign the list to the control as its data source.
And because I'm a LINQ enthusiast, I'll throw this in as an alternative solution:
var timeSlotValues = Enumerable.Range(0,5)
.Select(i => DateTime.Now.AddMinutes(i * 30))
.ToList();
Try using a dictionary to hold the key,value pairs like this:
string varname = "CalculationTimeDown";
Dictionary<string, DateTime> values = new Dictionary<string, DateTime>();
for (int i = 0; i <= 4; i++)
{
// Assemble the variable name
values.Add(varname + i.ToString("000"), DateTime.Now.AddMinutes((i) * 30));
}
Creating variables dynamically is not possible in c# as it is a strongly typed language. You can use dictionary in this case.
class Program
{
static void Main(string[] args)
{
Dictionary<string, DateTime> variables = new Dictionary<string, DateTime>();
for (int i = 0; i <= 4; i++) {
variables.Add(String.Format("CalculationTimeDown{0}", i.ToString("000")), DateTime.Now.AddMinutes(i * 30));
}
}
}

Create a empty array of points

I'm trying to create a empty array of points, for this i'm using the following
Point[] listapontos = new[]; //should create a empty point array for later use but doesn't.
Point ponto = new Point(); //a no coordinates point for later use
for (int i = 1; i <= 100; i++) //cycle that would create 100 points, with X and Y coordinates
{
ponto.X = i * 2 + 20;
ponto.Y = 20;
listapontos[i] = ponto;
}
I'm having some trouble, because I can't create a empty array of points. I could create a empty array of strings using a list, but since i will need two elements, a list isn't useful here.
Any hints? (hints for the problem are also welcome)
// should create a empty point array for later use but doesn't.
No, what you've specified just isn't valid syntax. If you want an empty array, you could use any of:
Point[] listapontos = new Point[0];
Point[] listapontos = new Point[] {};
Point[] listapontos = {};
However, then you've got an array with 0 elements, so this statement:
listapontos[i] = ponto;
... will then throw an exception. It sounds like you should either use a List<Point>, or create an array of size 101:
Point[] listapontos = new Point[101];
(Or create an array of size 100, and change the indexes you use - currently you're not assigning anything to index 0.)
It's important to understand that in .NET, an array object doesn't change its size after creation. That's why it's often convenient to use List<T> instead, which wraps an array, "resizing" (by creating a new array and copying values) when it needs to.
I could create a empty array of strings using a list, but since i will
need two elements, a list isn't useful here.
You can define a class like this:
public class Point
{
public double X {get;set;}
public double Y {get;set;}
}
Then you can use a List<Point>:
List<Point> points = new List<Point>();
points.Add(new Point(){X=10, Y=20});
The reason this doesn't work is 2-fold.
Firstly, when you say
Point[] listapontos = new[];
you are using invalid syntax. It should be more like
Point[] listapontos = new Point[100];
Now, secondly, when you are writing into the array, you are never creating a new point.
Point is a class, which means it is passed by reference. This means that whenever you are writing Ponto's address in, but not a new Ponto.
Instead what you should do is something more like
for(int i = 0; i < 100; i++)
{
listapontos[i] = new Point(i * 2 + 20, 20);
}
By using the new keyword, you are creating a new point in memory and storing that point's address in the array, instead of writing the address to the same point 100 times into the array.

Remove random entry until collection is empty

I'm pretty sure this is something basic but for some reason I just can't seem to get it work. First I'm not sure which Collection Type I should be using. I'm using C# for my Unity game and I'd like to store info like this:
# Name Number Value
1 Jim 15
2 Bob 21
3 Tim 31
4 Ron 26
Numbers 1-4 would be indexes so if I removed entry #3 with Tim, the table would look like:
# Name Number Value
1 Jim 15
2 Bob 21
3 Ron 26
I assume I should be using Dictionaries and that's what I tried. What I want to do with my code is to pick a random element, print it and then remove it. Rinse and repeat until the list is empty.
This is what I've been using for my code:
Dictionary<String, int> myDictionary = new Dictionary<String, int> ();
void Start()
{
myDictionary.Add ("Jim", 15);
myDictionary.Add ("Bob", 21);
myDictionary.Add ("Tim", 31);
myDictionary.Add ("Ron", 26);
}
void Update()
{
int totalEntries = myDictionary.Count;
int randNumber = Random.Range(1,totalEntries);
print(myDictionary[randNumber]);
myDictionary.Remove(randNumber);
}
It's not working. I've seen some suggestions about using RemoveAt or using HashTable but I haven't been able to get those working either. RemoveAt for some reason isn't recognized as a command and HashTable just kind of had the same issue. I am using "using System.Collections.Generic;" btw so that's not the problem. I'd like to mention that I'm pretty new to C# so what would help me the most would be actual working code that I can then edit to fit my game.
A Dictionary would not be ideal in this case.
I'd use a List of Tuples (or a List of a custom class).
List<Tuple<int, String, int>> myItems = new List<Tuple<int, String, int>>();
void Start()
{
myItems.Add(Tuple.Create(1, "Jim", 15));
myItems.Add(Tuple.Create(2, "Bob", 21));
myItems.Add(Tuple.Create(3, "Tim", 31));
myItems.Add(Tuple.Create(4, "Ron", 26));
}
Now there are a couple of ways to identify the object you wish to remove. First your initial approach (by index in the list):
void Update()
{
var rnd = new Random();
var randNumber = rnd.Next(0, myItem.Count);
myItems.Remove(myItems.ElementAt(randNumber));
}
Then by the actual value of the object:
void Update2()
{
var minValue = myItems.Min(i => i.Item1); // Gets the minimum value in first column (so to speak);
var maxValue = myItems.Max(i => i.Item1); // Gets the maximum value.
var rnd = new Random();
var randNumber = rnd.Next(minValue, maxValue + 1); // maximum value in Random.Next is exclusive.
var myObject = myItems.SingleOrDefault(o => o.Item1 == randNumber);
if (myObject != null)
myItems.Remove(myObject);
}
Which method you prefer is up to you and the requirements to solve the task. You might prefer by index but on the other hand you might prefer removing by value.
The drawback by the second method is that you might not remove an object at all when the random value is already removed.
Try this:
using System.Linq;
var r = new Random();
var i = r.Next(0, dic.Count);
var e = dic.ElementAt(i)
dic.Remove(e);
create an array with the same length, and out in each cell a number 1 to N. and shuffle the array. then delete each row by index
I ended up finding this link: http://wiki.unity3d.com/index.php/Choosing_the_right_collection_type
And have been able to solve my issue with ArrayLists. This is the part of the link that really helped me:
ArrayList myArrayList = new ArrayList(); // declaration
myArrayList.Add(anItem); // add an item to the end of the array
myArrayList[i] = newValue; // change the value stored at position i
TheType thisItem = (TheType) myArray[i]; // retrieve an item from position i
myArray.RemoveAt(i); // remove an item from position i
var howBig = myArray.Count; // get the number of items in the ArrayList
Thanks everyone for all the sugestions!

Will this array method keep updating the [0] index, or will it move the previous text back?

I have a method bringing in text every 600000 milliseconds, this is added to an array through the following method:
String[] namesArray = { };
Array.Resize(ref namesArray, namesArray.Length + 1);
namesArray[namesArray.Length - 1] = nameSplit;
I was curious, is this just replacing the array with the new text, or is it pushing the old index up to 1. Example if the text that came through was Jim, would this be placed in [0]. When the next comes through and it is "Harry", will "Jim" be pushed to 1 and "Harry" to [0]. Let me know if more code is required.
EDIT
Here is what your code is doing:
String[] namesArray = { }; // Create a new zero-element array.
Array.Resize(ref namesArray, namesArray.Length + 1); // Increase size of array by 1.
namesArray[namesArray.Length - 1] = nameSplit; // Assign to array's last element.
Thus, the end-result is that you would have a one-element array whose content is your nameSplit variable. This is equivalent to:
String[] namesArray = { nameSplit };
Subsequent calls will results in a new one-element array being created and assigned to namesArray.
Instead of manually resizing an array, consider using a List<T> instead. It's basically a self-resizing array. Instead of using two arrays, one for the names and another for the amounts, it's better to make a struct or class that groups a name and amount together, so you can use a single list:
public struct NameAndAmount
{
public string Name;
public int Amount;
public NameAndAmount(string name, int amount)
{
Name = name;
Amount = amount;
}
}
List<NameAndAmount> items = new List<NameAndAmount>();
items.Add(new NameAndAmount("test", 100));
However, if you need to perform lookups by name, you may want to use a Dictionary<TKey, TValue> instead, using the names as keys and the amounts as values:
Dictionary<string, int> items = new Dictionary<string, int>();
// Check if a name has been stored before:
if (items.ContainsKey(name))
int previousAmount = items[name];
// Store a name and amount:
items[name] = amount;

Creating a text parse for certain numbers

I have a textbox that I want to use to detect certain numbers (1 - 65) that have a value attached to them for doing math with the value.
Example: When a user types in the numerals "50" I want to associate that with the value 4500 (50, 4500).
So for each number 1 - 65 I want to assign a specific value, then when a user types a number 1 - 65 the program takes the associated value and assigns that to a variable so I can do math.
int lvl50 = 4500;
lvl50 = clvl;
tolvl = clvl - currentexp;
int ttlvl = (tlvl / ptexp) +1;
I'm looking for something like this.
I think you can use a Dictionary<int,int>
var values = new Dictionary<int,int> { { 1, 1000 }, { 50, 4500 } ... };
Then you can get the corresponding value of a number
values[50] // returns 4500
With user input:
var input = int.Parse(textBox1.Text);
var value = values[input];
Or use TryParse and ContainsKey methods to avoid possible exceptions
int input = -1;
if(int.TryParse(textBox1.Text, out input) && values.ContainsKey(input))
{
var value = values[input];
}
One of the methods I can think of is the use of a Dictionary<TKey, TValue> found under System.Collections.Generic;
values.Add(50, 4500);:
var values = new Dictionary<int, int>();
values.Add(50, 4500);
// ... etc
Create a formula/function:
If the numbers 1-65 values have any formula, than you can use create a method that will implement that formula value in order to use it.
Example:
public static int myFormula(int number)
{
return number * 90;
}
Dictionary:
If the following number matched values don't have any visible formula than you can use the Dictionary<int, int> to match them a specific value.
Example:
var myDic = Dictionary<int, int>() {
new { 1, 1 },
new { 50, 4500 },
};
From your code snippet, it looks (to me) like you may be calculating the value in the dictionary based on the key. You could place the logic for calculating the value in a separate method:
private int CalculateValue(int x)
{
// calculate value and return it
}
Then create a dictionary for a particular range of numbers like this:
var dict = Enumerable.Range(1, 65).ToDictionary(x => x, CalculateValue);
To use an element from the dictionary, just reference it using the key:
var matchingValue = dict[50]; // Lookup key 50
If it's possible the key may not exist, you can test for it:
var value = dict.ContainsKey(72) ? dict[72] : -1; // Assign some default value
Using a dictionary like the other answers suggest will work for you, but if your numbers 1-65 have no gaps, you can use a list (or even a simple array). The index of the list will be your input. That will be easier and more efficient than a dictionary.
var values = new List<int> { 1000 , 4500 };
Then you can get the corresponding value of user input:
int input, value;
if(int.TryParse(textBox1.Text, out input)){
if(values.Contains(input){
value = values[input];
}
}

Resources