How can I populate a string array with a parameter method C# - c#

I am trying to populate a string array called "items" with a pre written method called "insert".
The project has pre written code "b.insert("apple");" etc etc and the method given is "public void insert(T item)". I have to write the code in this method to make the "insert" function work. I have to pass "item" into "items" array but my for loop simply gives me the output "milk" 10 times. Because of this, I know that "item" value is simply changing to the last string passed in the insert method. Would I have to write a nested for loop where "item" is a counter? In this case "item" cannot be a counter because it is a string type. Should I convert "item" into an array?
I'm not sure why such a seemingly simple task has me stumped by I've been at it for hours and at this point I just want to sort it out for the sake of sanity.
thanks in advance
class Program
{
static void Main(string[] args)
{
BoundedBag<string> b = new BoundedBag<string>("ShoppingList", 10);
b.insert("apple");
b.insert("eggs");
b.insert("milk");
Console.WriteLine(b);
Console.ReadKey();
}
}
public interface Bag<T> where T : class
{
void insert(T item);
string getName();
bool isEmpty();
}
public class BoundedBag<T> : Bag<T> where T : class
{
private string bagName; // the name of the bag
protected int size; // max size of the bag
private int lastIndex;
protected T[] items;
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
rnd = new Random();
items = new T[size];
}
public string getName()
{
return bagName;
}
public bool isEmpty()
{
return lastIndex == -1;
}
public bool isFull()
{
if(items.Length >= size)
{
return true;
}
else { return false;}
}
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
for (int i = 0; i < size; i++)
{
items[i] = item;
}
}
}

You only want to insert one item into your array on insert so you shouldn't have a loop at all. Use the lastIndex field to insert one item into the appropriate place in the array:
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
if(isFull())
{
throw new FullBagException();
}
items[++lastIndex] = item;
}
Unfortunately your isFull method is also broken and your isEmpty method won't work properly unless you change the constructor.
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
items = new T[size];
lastIndex = -1;
}
public bool isFull()
{
return lastIndex == size - 1;
}

Related

C#: Why does my list not print the items? [duplicate]

This question already has answers here:
question about print List<T> to screen
(5 answers)
Print List of objects to Console
(3 answers)
Print list Object c#
(1 answer)
Why does every line in the .txt-file output end with 'System.int32'? C#
(3 answers)
Closed 2 years ago.
I'm trying to print out the int items inside the list but I get the following output, which is obviously not what I want to print:
YSolution.Dice
YSolution.Dice
YSolution.Dice
YSolution.Dice
YSolution.Dice
Source code:
class Dice
{
//defining variable and properties
private bool _hold = false;
private Random rnd;
public int Current { get; private set; }
public bool IsHolding
{
get { return _hold; }
set { _hold = value; }
}
public Dice()
{
Current = 0;
rnd = new Random(Guid.NewGuid().GetHashCode());
FRoll();
}
public int FRoll()
{
Current = rnd.Next(1, 7);
return Current;
}
class DiceCup
{
public List<Dice> Dices { get; } = new List<Dice>();
public DiceCup(int count)
{
for (int i = 0; i < count; i++)
{
Dices.Add(new Dice());
}
foreach (Dice aDice in Dices)
{
Console.WriteLine(aDice);
}
}
class Program
{
static void Main(string[] args)
{
DiceCup nbd = new DiceCup(count);
}
}
The method FRoll(); seem to not get called in the dice class for some reason, when a new item is added to the list.I really just want to print out the items in the List Dices but I do not get the output/result I want. Anyone who can spot the error?
Currently you're just calling ToString() on your Dice object. Since you haven't overriden ToString() this is just using the default object.ToString() implementation which returns the type name of the object (YSolution.Dice in your case).
You have a Current property on your dice that returns the value of the dice, if you call this method then that will return the value of the dice, which you can then print: change Console.WriteLine(aDice); to Console.WriteLine(aDice.Current);.
Alternatively, as others have pointed out, you can override ToString() on your Dice class to return the current value of the dice:
class Dice
{
//defining variable and properties
private bool _hold = false;
private Random rnd;
public int Current { get; private set; }
public bool IsHolding
{
get { return _hold; }
set { _hold = value; }
}
public Dice()
{
Current = 0;
rnd = new Random(Guid.NewGuid().GetHashCode());
FRoll();
}
public int FRoll()
{
Current = rnd.Next(1, 7);
return Current;
}
public override string ToString()
{
return Current.ToString();
}
}
you want to implement the ToString-method:
public string ToString()
{
return Current.ToString();
}
Besides overriding the ToString method, as mentioned in other answers, you could also collect the results from the dice and print those:
foreach (int result in Dices.Select(d => d.Current))
{
Console.WriteLine(result);
}
The Select method is defined in the System.Linq namespace.

How to use a Stack's Pop method in another method

I am attempting to write a program for an assignment that Pops and adds the first 2 items in a Stack. The program has a Pop method, but I would like to know how to call the method within the Add method. This Add is supposed to Pop the top two items in a stack, get their sum, and Push that sum to the stack. In my code below I call the Pop method twice inside the Add method, but when I display the stack, the stack still has all of the original values. Is there something more/else I need to go to get the Pop method to work?
class StackEmptyException : ApplicationException
{
public StackEmptyException(String message) : base(message)
{
}
}
class MathStack
{
private int[] dataStack;
private int size;
private int top = -1;
public bool IsEmpty()
{
return top == -1;
}
public bool IsFull()
{
return top == size - 1;
}
public void Push(int i)
{
dataStack[++top] = i;
}
public int Pop()
{
if (IsEmpty())
throw new StackEmptyException
("Stack empty -- cannot pop");
else
return dataStack[top--];
}
public int Top()
{
if (IsEmpty())
throw new StackEmptyException
("Stack empty -- top undefined");
else
return dataStack[top];
}
public MathStack()
{
dataStack = new int[10];
}
public MathStack(int s)
{
size = 10;
dataStack = new int[size];
}
public void LoadStack(int v)
{
dataStack[++top] = v;
}
public void Display()
{
int[] display = new int[dataStack.Length];
for (int i = 0; i < dataStack.Length; i++)
{
display[i] = dataStack[i];
Console.WriteLine("{0}", display[i]);
}
}
public void Add()
{
int add1 = dataStack[0];
int add2 = dataStack[1];
Pop();
Pop();
int sum = add1 + add2;
Console.WriteLine("Sum: {0}", sum);
}
}
class Program
{
static void Main(string[] args)
{
MathStack stack1 = new MathStack();
stack1.Push(9);
stack1.Push(8);
stack1.Push(7);
stack1.Push(6);
stack1.Push(5);
stack1.Push(4);
stack1.Push(3);
stack1.Push(2);
stack1.Push(1);
stack1.Push(0);
stack1.Display();
stack1.Add();
stack1.Display();
Console.ReadLine();
}
}
There are two things wrong with your code.
First, the Display method displays the whole array. Except that since you're not physically removing the items from the array, you need to stop at the index top:
public void Display()
{
if (IsEmpty())
{
Console.WriteLine("Empty");
return;
}
for (int i = 0; i <= top; i++)
{
Console.WriteLine(dataStack[i]);
}
}
The second issue is your Add. From what I understand, you want to pop the last two items, sum them, and push the result. In your implementation, you are actually summing the first two items (not the last two). A better version would be:
public void Add()
{
int add1 = Pop();
int add2 = Pop();
int sum = add1 + add2;
Console.WriteLine("Sum: {0}", sum);
Push(sum);
}
Notice how I do not directly access dataStack. If your API is correctly implemented, it should not be needed.

How to make an array of objects visible to other functions

In my current program I am building an array of objects and then populating it, however I need to then access this populated array from another function within the same class. In C I would do this by making the array global, but global variables dont exist in C# and when I try to use the "Static" parameter it says arrays cant be static.
namespace FormsTest1
{
public partial class Form1 : Form
{
public int AppCount;
public static applications[] appList;
public Form1() //Main Entry point of program
{
IEnumerable<int> apps = VolumeMixer.EnumerateApplications();
AppCount = apps.Count();
int i = 0;
applications[] appList = new applications[AppCount];
foreach (int app in apps)
{
appList[i] = new applications();
appList[i].setProcessID(app);
appList[i].populate();
i++;
}
for (int j = 0; j < AppCount; j++) { ChannelSelect1.Items.Add(appList[j].Name); }
}
private void ChannelSelect1_SelectedIndexChanged(object sender, EventArgs e)
{
for (int k = 0; k < AppCount; k++)
{
if (ChannelSelect1.Text == appList[k].Name) //<-- This array is not the one I populate in Form1()
{ Channels[0] = appList[k].PID; }
}
}
public class applications
{
public int PID;
public string ProcessName;
public string WindowName;
public string Name;
public string Path;
public void setProcessID(int ID) { PID = ID; }
public string getProcessName() { return ProcessName; }
public string getWindowName() { return WindowName; }
public string getName() { return Name; }
public string getPath() { return Path; }
public void populate()
{
//stuff
}
}
}
I cant pass the array into the other functions cause they are event driven, and I need the index-ability of arrays.
How do I declare and populate an array of objects in one function, and then use that array in another function in the same class?
Change your constructor from
applications[] appList = new applications[AppCount];
to
appList = new applications[AppCount];
You should initialize your instance field instead of creating a new local one.
Btw: It is not necessary to make the array static.

With Statement in C# like that of AS3/GML

I'm making a game using Monogame, and I've been trying to figure out how to implement a function that acts similarly to AS3's and GML's with statement.
So far I have a system that works, but not entirely the way I want it to. I store my GameObjects in a Dictionary of Lists. This is so I can get to the specific type of object I want to access without having to loop through a list of ALL objects. The key used is the name of the type.
public static Dictionary<string, List<GameObject>> All =
new Dictionary<string, List<GameObject>>();
I access all of a specific type of object using AllOf. If a List containing that type exists in the Dictionary, it returns that List, else it returns an empty list.
public static List<GameObject> AllOf(Type type)
{
string key = type.Name;
if(All.ContainsKey(key))
{
return All[key];
}
return new List<GameObject>();
}
An example of how these are implemented
public override void Update(GameTime gameTime)
{
List<GameObject> list = Instance.AllOf(typeof(Dummy));
for(int i = 0; i < list.Count; i++)
{
list[i].Update(gameTime);
list[i].foo += bar;
}
}
But I'd rather use something similar to the AS3/GML with statement, which would also allow for other, non-member codes to be executed.
with(typeof(Dummy))
{
Update(gameTime);
foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
Is there a way to accomplish this? My end goal is just to make my code look a little cleaner, and make it easier to make a lot of changes without having to type out a for loop each time.
No such syntax exists in C#, but you can access methods within the for that have nothing to do with the collection:
public override void Update(GameTime gameTime)
{
List<GameObject> list = Instance.AllOf(typeof(Dummy));
for(int i = 0; i < list.Count; i++)
{
list[i].Update(gameTime);
list[i].foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
}
Note that you can also use foreach, which is a little cleaner if you don't need the indexer:
foreach(var item in list)
{
item.Update(gameTime);
item.foo += bar;
int fooBar = 2;
someObject.someMemberFunction(fooBar);
}
try
using(Object myObject = new Object()){
}
i think this might be what your looking to use?
I have a small solution for this use case. This may be a bit of a necropost, but it is a pretty neat solution. Additionally, I think all of the C# features that are required existed back when this question was asked.
You can do something very similar to the GML with(x){} by using some form of delegate as a parameter to a static method, and passing a lambda as that parameter. The function can even be genericised, and you can call it without the class name by the using static statement. You will need to explicitly provide the typed/named parameter, but it is possible. You would need to hook it up to your own types, but the general idea is:
namespace NiftyStuff {
public static class With {
public static void with<T>(Action<T> proc) where T : GameObj {
var typeName = typeof(T).Name;
foreach (var item in GameObj.AllOf(typeName)) { proc((T)item); }
}
}
public class GameObj {
private static Dictionary<string, List<GameObj>> All = new Dictionary<string, List<GameObj>>();
public static List<GameObj> AllOf(string name) {
return All.ContainsKey(name) ? All[name] : null;
}
public static void Add(GameObj foo) {
string typeName = foo.GetType().Name;
List<GameObj> foos = All.ContainsKey(typeName) ? All[typeName] : (All[typeName] = new List<GameObj>());
foos.Add(foo);
}
public float x, y, angle;
public GameObj() { x = y = angle = 0; }
public void Destroy() { AllOf(GetType().Name)?.Remove(this); }
}
public class Enemy : GameObj {
public float maxHealth, curHealth;
public Enemy() : base() { maxHealth = curHealth = 300; }
public Enemy(float health) : base() { maxHealth = curHealth = health; }
public bool Damage(float amt) {
if (curHealth > 0) {
curHealth -= amt;
return curHealth <= 0;
}
return false;
}
}
public class Pumpkin : GameObj {
public bool exists = false;
public Pumpkin() : base() { exists = true; }
public bool LookAt() { return (exists = !exists); }
}
}
Actually using the above code would work as follows:
using NiftyStuff;
using static NiftyStuff.With;
//...
with ((Enemy e) => {
if (e.Damage(50)) {
Log("Made a kill!"); // Whatever log function you have...
}
});
with ((Pumpkin p) => {
if (p.LookAt()) {
Log("You see the pumpkin");
} else {
Log("You no longer see the pumpkin");
}
});
While not exactly like GML's with statement, it would at least let you run code against all of the registered objects of some type.
One important note is that you can't destroy objects inside of a with this way (due to concurrent modification of a collection while iterating it). You would need to collect all objects to be destroyed, and then remove them from the list in All, typically in a game loop this is done at the end of a frame.
Hope this helps, despite being 2 years out of date.

Make Length property available for my class C#

I want to create class Massive and to add a method for adding two massives. But property Length for my class instances doesn't work.
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
How to make it available for my class?
It's my code.
class Massiv
{
public Massiv(int n)
{
mas = new int[n];
Random rand = new Random();
for (int i = 0; i < mas.Length; ++i)
{
mas[i] = rand.Next(0, 10);
}
}
public void ShowAll()
{
Console.WriteLine("Massive: ");
foreach (var elem in mas)
{
Console.Write(elem + " ");
}
Console.WriteLine();
}
public void ShowElement(int index)
{
try
{
Console.WriteLine("mas[{0}] = {1}", index, mas[index]);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Error!");
}
}
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
public int this[int index]
{
get { return mas[index]; }
set { mas[index] = value; }
}
private int[] mas;
}
}
It seems like you have not declared any Length property, therefore, the compiler cannot possibly know one.
Basically, add this to your class:
public int Length {
get {
}
set {
}
}
In the getter, you need to return the value of the property, while in the setter, you will have to change it.
In this case, you seem to want to retrieve the length of your internal array. If you do not need write-access, you can skip the set part:
public int Length {
get {
return mas.Length;
}
}
Just add this property to your class:
public int Length {
get { return mas.Length; }
}
Note it has only a get accessor, which makes it read only (You don't seem to need write access since you initialize the private array in the constructor).
public int Length {
get {
return mas.Length;
}
}

Categories

Resources