Store reference of an ushort in an array in c# - c#

I would like to store reference of an ushort variable in an ushort array, so that the value of the variable changes when I change the values inside the ushort array. Here is my sample code which will give a clear picture of what I'm trying to achieve.
public void IndexSetter(List<int> indexVal,Rootobject objectVal)
{
ushort[] refereneArray = new ushort[8]
{
objectVal.index1, objectVal.index2,
objectVal.index3 , objectVal.index4,
objectVal.index5, objectVal.index6,
objectVal.index7, objectVal.index8
};
for(int j = 0; j< indexVal.Count;j++)
{
refereneArray[j] =(ushort) indexVal[j];
}
}
Instead of storing the values like from above code , I need to store the reference so that the changes in indexVal list reflect in the values of index1, index2.. etc

I´d suggest not to have 8 indexes with the exact same name (except a number). Give every member of your class a name describing what it´s ment to be, however index6 isn´t really self-explanatory.
Having said this what you can do is to have one array of indexes within your class itself:
class Rootobject
{
public int[] Indexes { get; set; }
}
Now you can access them as follows:
public void IndexSetter(List<int> indexVal, Rootobject objectVal)
{
for(int i = 0; i < indexVal.Count; i++)
objectVal.Indexes[index] = indexVal[i];
}
Or even shorter:
objectVal.Indexes = indexVal.Cast<ushort>().ToArray();

You can do it with unsafe code, using array of pointers like this:
static unsafe void IndexSetter(IList<ushort> indexVal, Rootobject objectVal) {
fixed (ushort* r1 = &objectVal.index1)
fixed (ushort* r2 = &objectVal.index2) {
ushort*[] refereneArray = {r1, r2};
for (int j = 0; j < indexVal.Count; j++) {
*refereneArray[j] = (ushort) indexVal[j];
}
}
}
Should you really do this in real application is another story. There is very high chance that there is a better way to solve your problem, but you didn't tell us what the actual problem is.
If perfomance is not critical - you can use reflection:
static void IndexSetter2(IList<ushort> indexVal, Rootobject objectVal) {
int i = 0;
foreach (var field in objectVal.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(c => c.Name.StartsWith("index") && c.FieldType == typeof(ushort))
.OrderBy(c => c.Name)) {
field.SetValue(objectVal, indexVal[i]);
i++;
}
}

Related

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;

Defining constants in C#

I'm C/C++ to C# developer.
I need to do something like below,
#define LEN 20
int data[LEN];
Since C# doesn't support #define, many forums suggests to declare a const variable. A const variable might help me for below, but not for above.
for (int a = 0; a < LEN; a++)
{
x += data[LEN - a - 1];
}
So, how do I use the constant for array declarations as well?
C# lets you create constants of several built-in types using const keyword.
Constants can be numbers, Boolean values, strings, or a null reference.
Here is a small example:
public class Demo {
public const int Length = 20;
public void Main(string[] args) {
var data = new int[Length];
for (var i = 0 ; i != Length ; i++) {
data[i] = 2*i + 3;
}
}
}
Note: C# naming guidelines suggest avoiding all-caps naming.
Actually you should use it for the instantiation of the array:
const int LEN = 20;
int[] data = new int[LEN];
you could do something like this
static readonly int LEN = 20;
static void Main(string[] args)
{
int[] data = new int[LEN];
for (int a = 0; a < LEN; a++)
{
int x = data[LEN];
}
}
please note that that date array will be default initialized to 0.
also, you will get System.IndexOutOfRangeException for int x = data[LEN]; because you are asking for the 20th index and there is no such index in the array
You should not use constants to declare an array length. Also, there are many data structures in C# that allow you to have a dynamic size array/list/dictionary...

Modifying Objects in C#

(If you can think of a better title, please let me know.)
I’m working on a route optimization program. I'm starting with a list of points which the route needs to include. My first step is to create a list of all possible routes (permutations). I then remove any route I can (for example, if one stop must precede another). Once that's done I calculate the distance and time between each point, in each possible route. Each point is an object (TPoint) and all the distance and time values are stored in a separate class called TData, which is stored in each instance of TPoint. My problem is this: when I try to update the TData in, say, the first stop, in the first possible route it will update the TData for that same TPoint in each possible route. This is because the class is a reference type and is stored on the heap. I’m looking for a solution that allows me to store the TData on each TPoint.
Here's some example code (the following code demonstrates how when I modify one object (TPoint), I'm only actually using the reference to modify the object on the heap):
Main
// Let's create a list of points we need to hit.
List<TPoint> lstInitial = new List<TPoint>();
lstInitial.Add(new TPoint("A", new TData(-1, -1)));
lstInitial.Add(new TPoint("B", new TData(-1, -1)));
lstInitial.Add(new TPoint("C", new TData(-1, -1)));
// Now let's get all possible routes
IList<IList<TPoint>> lstPermutations = Permutations(lstInitial);
// Let's write these values to the first point, in the first possible route.
lstPermutations[0][0].oTData.distance = 10;
lstPermutations[0][0].oTData.minutes = 20;
foreach (IList<TPoint> perm in lstPermutations)
{
foreach (TPoint p in perm)
{
Response.Write(p.id + "|" + p.oTData.distance + "|" + p.oTData.minutes);
Response.Write(" ");
}
Response.Write("<br />");
}
Permutation Function
// Get permutations
private static IList<IList<T>> Permutations<T>(IList<T> list)
{
List<IList<T>> perms = new List<IList<T>>();
// If the list is empty, return an empty list.
if (list.Count == 0)
{
return perms;
}
// This is a loop method to get the factorial of an integer
int factorial = 1;
for (int i = 2; i <= list.Count; i++)
{
// shortcut for: factorial = factorial * i;
factorial *= i;
}
for (int v = 0; v < factorial; v++)
{
//List<T> s = new List<T>(list);
List<T> s = new List<T>(list);
int k = v;
for (int j = 2; j <= list.Count; j++)
{
int other = (k % j);
T temp = s[j - 1];
s[j - 1] = s[other];
s[other] = temp;
k = k / j;
}
perms.Add(s);
}
return perms;
}
Classes
public class TPoint
{
public TPoint(string _id, TData _oTData)
{
id = _id;
oTData = _oTData;
}
public string id { get; set; }
public int someInt { get; set; }
public TData oTData { get; set; }
}
public class TData
{
public TData(int _distance, int _minutes)
{
distance = _distance;
minutes = _minutes;
}
public int distance { get; set; }
public int minutes { get; set; }
}
It kind of seems as if I've managed to paint myself into a corner. I can think of a few solutions, but they seem messy so I figured I'd ask the experts on this one.
Edit
Can anyone think of why this wouldn't be a good idea?
Instead of this, which modifies the object on the heap (and affects every point in each possible route):
lstPermutations[0][0].oTData.distance = 10;
lstPermutations[0][0].oTData.minutes = 20;
Use this, which just creates a new instance of the class:
TPoint oTPoint = new TPoint(lstPermutations[0][0].id, new TData(10, 20));
lstPermutations[0][0] = oTPoint;
If you make TData a struct then it will be copied by value and not by reference. Otherwise you'll have to make a shallow clone which copies values.
Why not make your simple TData type immutable by removing the set accessors, so that it won't matter much if it is copied by value or copied by reference. It could be functionally equivalent to Tuple<int, int>.
Whether the object is stored on the heap or somewhere else is probably unimportant. If you decide to make the object immutable, it will be natural to make it a struct, though, but a class is also fine.

Modifying a particular item in a list of structures

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;
}
}
}

How to read values from the ArrayList of Structures?

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;

Categories