c# populating multiple cells from array - c#

I have an array with six numbers. I'd like to perform a certain equation on each of these numbers, and then place the result in a series of textboxes, corresponding with the position within the array.
Eg. result of equation on the value of pos 0 in array goes into textbox01, result of pos1 into textbox02, etc.
I have the following code:
for (int i = 0; i <= 5; i++)
{
if ((Convert.ToInt32(statArray.GetValue(i))-10)%2 == 0)
{
//txtMod01.Text = Convert.ToString((Convert.ToInt32(statArray.GetValue(i)) - 10) / 2);
}
else
{
txtMod01.Text = Convert.ToString((Convert.ToInt32(statArray.GetValue(i)) - 11) / 2);
}
}
I'd like to automatically change the name of the textbox (eg. txtMod01) to the following textbox in the series (txtMod02).
Is their any way to do this?

You can use reflection, which allows you manipulate types at runtime:
// property name "txtMod0x"
string propertyName = "txtMod" + i.ToString().PadLeft(2, '0');
// get the property from the current type
PropertyInfo prop = this.GetType().GetProperty(propertyName);
if (prop != null)
{
// get the property value (the TextBox in this case)
var textBox = (TextBox)prop.GetValue(this, null);
string val = Convert.ToString((Convert.ToInt32(statArray.GetValue(i)) - 11) / 2);
textBox.Text = val;
}

You could put your Textboxs in an array as well, something like:
TextBox[] boxes = new TextBox[]{txtbox01, txtbox02, txtbox03, txtbox04, txtbox05, txtbox06};
int[] values = new int[]{val1, val2,val3, val4,val5, val6};
for(int i=0; i < values.Count; ++i)
{
//perform calculations
...
boxes[i].Text = values[i];
}

Related

Sorting an array of enumeration

Hello I have an array of enumerations, and I'm trying sort that array by their enumeration value and get the array index's of the top
private enum Values
{
LOW,
MEDIUM,
HIGH
}
private Values[] Settings = new Values[10];
Settings[0] = LOW;
Settings[1] = HIGH;
Settings[2] = MEDIUM;
Settings[3] = LOW;
Settings[4] = LOW;
Settings[5] = LOW;
Settings[6] = LOW;
Settings[7] = LOW;
Settings[8] = MEDIUM;
Settings[9] = MEDIUM;
Basically now, with what I have above, I need to sort the settings array by enumeration value and get the array indexes of the top (let's say 3) items;
So I'd get back values 1, 2, 8
The platform I'm using does not support LINQ so those handy functions are not available.
I've been trying to wrap my head around this but it would help to have another pair of eyes.
thanks.
Implement a wrapper reference type,
class ValueWrapper : IComparable<ValueWrapper>
{
public Values Value { get; set; }
public int Index { get; set; }
public int CompareTo(ValueWrapper other)
{
return this.Value.CompareTo(other.Value) * -1; // Negating since you want reversed order
}
}
Usage -
ValueWrapper[] WrappedSettings = new ValueWrapper[10];
for(int i = 0; i < WrappedSettings.Length; i++)
{
WrappedSettings[i] = new ValueWrapper { Value = Settings[i], Index = i };
}
Array.Sort(WrappedSettings);
WrappedSettings will be sorted as you specified, preserving the indexes they were in the original array.
how about this:
Values first = Values.Low,second = Values.Low,third = Values.Low;
int firstI = -1,secondI = -1, thirdI = -1;
for(int i = 0;i < Settings.Length;i++)
{
if(Settings[i] > first || firstI == -1)
{
third = second;
thirdI = secondI;
second= first;
secondI= firstI;
first = Settings[i];
firstI = i;
}
else if(Settings[i] > second || secondI == -1)
{
third = second;
thirdI = secondI;
second = Settings[i];
secondI = i;
}
else if(Settings[i] > third || thirdI == -1)
{
third = Settings[i];
thirdI = i;
}
}
So, since you say you work in an environment where Linq is not available, I assume that other things like generics, nullables and so on will not be available either. A very low-tech solution.
Basic idea:
For every possible enum value, from highest to lowest, go through the list. If we find that value, output it and remember how many we have output. If we reach 3, stop the algorithm.
So, we first look for HIGH in the list, then for MEDIUM and so on.
class Program
{
private enum Values
{
LOW,
MEDIUM,
HIGH
}
static void Main(string[] args)
{
// Sample data
Values[] settings = new Values[10];
settings[0] = Values.LOW;
settings[1] = Values.HIGH;
settings[2] = Values.MEDIUM;
settings[3] = Values.LOW;
settings[4] = Values.LOW;
settings[5] = Values.LOW;
settings[6] = Values.LOW;
settings[7] = Values.LOW;
settings[8] = Values.MEDIUM;
settings[9] = Values.MEDIUM;
// Get Values of the enum type
// This list is sorted ascending by value but may contain duplicates
Array enumValues = Enum.GetValues(typeof(Values));
// Number of results found so far
int numberFound = 0;
// The enum value we used during the last outer loop, so
// we skip duplicate enum values
int lastValue = -1;
// For each enum value starting with the highest to the lowest
for (int i= enumValues.Length -1; i >= 0; i--)
{
// Get this enum value
int enumValue = (int)enumValues.GetValue(i);
// Check whether we had the same value in the previous loop
// If yes, skip it.
if(enumValue == lastValue)
{
continue;
}
lastValue = enumValue;
// For each entry in the list where we are searching
for(int j=0; j< settings.Length; j++)
{
// Check to see whether it is the currently searched value
if (enumValue == (int)settings[j])
{
// if yes, then output it.
Console.WriteLine(j);
numberFound++;
// Stop after 3 found entries
if (numberFound == 3)
{
goto finished;
}
}
}
}
finished:
Console.ReadLine();
}
}
Output is as requested 1,2,8
I'm not sure if this is exactly what you want because it doesn't sort the original array, but one way to get the indexes of the top three values is to simply store the indexes of the top values in another array. Then we can loop through the original array, and for each item, see if it's larger than any of the items at the indexes we've stored so far. If it is, then swap it with that item.
For example:
// Start the topIndexes array with all invalid indexes
var topIndexes = new[] {-1, -1, -1};
for (var settingIndex = 0; settingIndex < Settings.Length; settingIndex++)
{
var setting = Settings[settingIndex];
var topIndexLessThanSetting = -1;
// Find the smallest topIndex setting that's less than this setting
for (int topIndex = 0; topIndex < topIndexes.Length; topIndex++)
{
if (topIndexes[topIndex] == -1)
{
topIndexLessThanSetting = topIndex;
break;
}
if (setting <= Settings[topIndexes[topIndex]]) continue;
if (topIndexLessThanSetting == -1 ||
Settings[topIndexes[topIndex]] < Settings[topIndexes[topIndexLessThanSetting]])
{
topIndexLessThanSetting = topIndex;
}
}
topIndexes[topIndexLessThanSetting] = settingIndex;
}
// topIndexes = { 1, 2, 8 }

listboxes passing values from each other

I'm trying to multiply the values of 2 listboxes together and make their product appear at another list box I'm getting the results I need but the problem is when I rerun the loop using a command button the listbox removes the next instance of the first value calculated by ppc[i] * qty[i] but when I try to remove the the listBox4.Items.Remove(ppc[i] * qty[i]) it reprints the whole array again from first element to last element
string myString = textBox1.Text.ToString();
int index = listBox6.FindString(myString, -1);
int[] qty = new int[99];
int[] ppc = new int[99];
int[] gt1 = new int[99];
listBox3.Items.Add(listBox5.Items[index]);
listBox1.Items.Add(textBox2.Text.ToString());
if (index != -1)
{
listBox6.SetSelected(index, true);
listBox2.Items.Add(textBox1.Text); //name
}
listBox3.Items.Add(listBox5.Items[index]);
listBox3.Items.Remove(listBox5.Items[index]);
for (int i = 0; i != listBox2.Items.Count ; i++)
{
ppc[i] = Convert.ToInt32(listBox3.Items[i]);
qty[i] = Convert.ToInt32(listBox1.Items[i]);
listBox4.Items.Remove(ppc[i] * qty[i]);
listBox4.Items.Add((ppc[i] * qty[i]));
}
My understanding is that this loop works once, and then when it is re-run it is out of order. Are you making sure to clear listbox4 each time this loop is executed? Also since listBox2 isn't used, it is probably better not to use it for your loop bounds.
if(listBox1.Items.Count == listBox3.Items.Count)
{
int rowCount = listBox1.Items.Count;
listBox4.Items.Clear();
for (int i=0; i < rowCount; i++)
{
ppc[i] = Convert.ToInt32(listBox3.Items[i]);
qty[i] = Convert.ToInt32(listBox1.Items[i]);
listBox4.Items.Insert(i , (ppc[i] * qty[i]));
}
}

My array doesn't seem to work in methods outside the main?

http://pastebin.com/98q57mzj
This has to do with a textbox array and an int array. Somehow, the values of the arrays seem to work within the main method, but not in other methods.
So from lines 34 to 44, I assign values to my arrays in the main, and then from lines 48 to 56 I use a for loop to make it so only certain keys are allowed when typing in the textboxes. Then in another method from lines 64 to 70, I try to use another for loop to make a "" string value equal to 0, or otherwise grab the value within the textbox and set that value to the variables within the numbers[] array. This doesn't seem to work. Changing the values in the textboxes doesn't seem to change the values of the numbers[] array. However, it does work if I type it out, as I did from lines 71 to 94. I don't want to take the easy way out and just type it out, I want to know why this loop isn't working so I can learn more about arrays and methods and so I'd know how to fix similar issues in the future.
For convenience:
public Form1()
{
InitializeComponent();
inputs[0] = textBox1;
inputs[1] = textBox2;
inputs[2] = textBox3;
inputs[3] = textBox4;
inputs[4] = textBox5;
numbers[0] = oneYear;
numbers[1] = twoYear;
numbers[2] = threeYear;
numbers[3] = fourYear;
numbers[4] = moreYear;
textBox6.ReadOnly = true;
for (int i = 0; i <= 4; i++)
{
inputs[i].KeyDown += (obj, args) =>
{
Keys[] allowedKeys = { Keys.Back, Keys.Next, Keys.Delete, Keys.Left, Keys.Right };
args.SuppressKeyPress = !allowedKeys.Contains(args.KeyCode) && (args.KeyValue < 48 || args.KeyValue > 57);
};
inputs[i].Text = 0.ToString();
}
}
private void autobots()
{
try
{
//find out why this doesn't work
for (int i = 0; i <= 4; i++)
{
if (inputs[i].Text == "")
numbers[i] = 0;
else
numbers[i] = Convert.ToInt32(inputs[i].Text);
}
/*if (textBox1.Text == "")
oneYear = 0;
else
oneYear = Convert.ToInt32(textBox1.Text);
if (textBox2.Text == "")
twoYear = 0;
else
twoYear = Convert.ToInt32(textBox2.Text);
if (textBox3.Text == "")
threeYear = 0;
else
threeYear = Convert.ToInt32(textBox3.Text);
if (textBox4.Text == "")
fourYear = 0;
else
fourYear = Convert.ToInt32(textBox4.Text);
if (textBox5.Text == "")
moreYear = 0;
else
moreYear = Convert.ToInt32(textBox5.Text);*/
oneTotal = oneYear * 24;
twoTotal = twoYear * 27;
threeTotal = threeYear * 30;
fourTotal = fourYear * 33;
moreTotal = moreYear * 36;
total = oneTotal + twoTotal + threeTotal + fourTotal + moreTotal;
textBox6.Text = total.ToString();
//label6.Text = ("$") + total.ToString();
}
catch
{
textBox6.Text = "";
//label6.Text = "";
}
}
Your for loop is working correctly....However, in order to shed some light on why this isn't working the way you need it to:
numbers[0] = oneYear;
numbers[1] = twoYear;
numbers[2] = threeYear;
numbers[3] = fourYear;
numbers[4] = moreYear;
When you do this you are storing the value of the variables into the array...not the variables themselves.
for (int i = 0; i <= 4; i++)
{
if (inputs[i].Text == "" || inputs[i] == null)
numbers[i] = 0;
else
here you set the value in the i position of the numbers array. to the value of whats in the text box. This does not change the value of your variables ("oneYear", "twoYear", etc..)
numbers[i] = Convert.ToInt32(inputs[i].Text);
}
but here you are are using the variables (ie "oneYear", "twoYear") which have not
had a new value stored in them. Remember the numbers[] array does not directly effect these variables
the numbers[] array (because it is an array of type int) only stored the values of these variables not a reference to the variables themselves. Because of this the code here does not do what you want it to.
oneTotal = oneYear * 24;
twoTotal = twoYear * 27;
threeTotal = threeYear * 30;
fourTotal = fourYear * 33;
moreTotal = moreYear * 36;
total = oneTotal + twoTotal + threeTotal + fourTotal + moreTotal;
textBox6.Text = total.ToString();
In order to get this code to work correctly you would need to use the values in the numbers[] array. Like this:
oneTotal = numbers[0] * 24;
twoTotal = numbers[1] * 27;
threeTotal = numbers[2] * 30;
etc...
When you do this it will output the correct results to textBox6.
The first section of code I pasted is only useful if the oneYear, twoYear, threeYear, fourYear, moreYear variables have a non-zero default value or have a value set before it ever gets to this code, and because you are using the numbers[] array to store the values from the text box you will not see the calculations you want to see, unless you use the numbers[] array values. Or if you're dead set on using the oneYear, twoYear... variables just use the if-else statments you have commented out, or put:
oneYear = numbers[0];
twoYear = numbers[1];
etc..
A little more clarification:
I think the reason you might have gotten a little confused here is because you are using two different types of arrays. A TextBox array used to store your textboxes, and an int array used to store the values in the text boxes. The TextBox array is storing objects...or a reference(pointer) to an object. So when you say inputs[0] = textBox1; you are telling the program to store the reference to textBox1 in the first element of the inputs[] array allowing you to directly manipulate the textBoxes stored in this array, but because the int type is a primary data type when it is stored in an array only its value is stored, not the variable itself.
Last thing:
You would need to create/use a wrapper class for your int variables in order to do what you are trying to do the way you are trying to do it.

Detecting an empty array without looping

How can i find out an array is empty or not, without looping?!
is there any method or anything else?
I mean, in some code like this:
string[] names = new string[5];
names[0] = "Scott";
names[1] = "jack";
names[2] = null;
names[3] = "Jones";
names[4] = "Mesut";
// or
int[] nums = new int[4];
nums[0] = 1;
// nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
or some code like this:
using System;
class Example
{
static void Main()
{
int size = 10;
int counter;
string[] str = new string[size];
for (counter = 0; counter < size; counter++)
{
str[counter] = "A" + counter;
}
str[3] = null;
if (counter == size)
Console.WriteLine("Our array is full!");
if(counter < size)
Console.WriteLine("Our array is not full");
for (int i = 0; i < size; i++)
{
Console.WriteLine(str[i]);
}
}
}
is there anything else for detecting an empty array without looping?
An array just contains a number of elements. There's no concept of an array being "empty" just because each element happens to contain the default value (0, null, or whatever).
If you want a dynamically sized collection, you should use something like List<T> instead of an array.
If you want to detect whether any element of a collection (whether that's a list, an array or anything else) is a non-default value, you have to do that via looping. (You don't have to loop in your source code, but there'll be looping involved somewhere...)
There is no other way than looping through, even LINQ also does the looping automatically.
Instead, use a list<> and check if (listName!=null && listName.Length!=0)
Hope it helps :)
You can use LINQ for that, to check if any element is empty in the array you just can do:
var hasNulls = myArray.Any( a => a == null );
Or if you want to select the ones with values:
var notNulls = myArray.Where( a => a != null );

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