How to read Object list item in C# - c#

I have a object that prints a multidimensional matrix, e.g:
namespace example;
Public class Object()
{
int lines, cols;
int matrix[,];
public Object(int lines, int cols)
{
this.lines = lines;
this.cols = cols;
matrix = new int[lines,cols];
PrintMatrix()
}
public void PrintMatrix()
{
Random rand = new Random();
Console.WriteLine();
for(int i = 0; i < lines ;i++)
for(int j = 0, j < cols; j++)
matrix[i,j]= rand.nextInt(1,10);
Console.WriteLine(matrix[i,j));
}
}
i want to print in console output something like this:
matrix 1:
1 2 3
4 2 4
3 3 1
matrix 2:
2 3 4 4
1 1 2 2
3 3 4 4
1 1 8 8
matix 3:
...
So i have tried to insert the Object inside of List or Arraylist:
static void Main(string[] args)
{
List<Object> conteiner = new List<Object>();
Object foo = new Object(3,3);
Object anotherFoo = new Object(4,4);
conteiner.add(foo);
conteiner.add(anotherFoo);
foreach(object item in conteiner)
{
console.WriteLine(item)
}
}
it prints :
example.Object.foo;
example.Object.anotherFoo;
instead of multidimentional arrays.
What I´m doing wrong and how can i improve this solution?

If you want you could override the default ToString() method of your object.
public override string ToString()
{
return PrintMatrix();
}
Of course this forces you to make PrintMatrix() return a string but I would suggest to do it that way as it makes for better because more reusable code.
I would write something like the following :
public string PrintMatrix()
{
string result = string.Empty;
for(int i = 0; i < lines ;i++)
{
for(int j = 0, j < cols; j++)
{
matrix[i,j] = rand.Next(1,10);
result += $"{matrix[i,j]} ";
}
result += Environment.NewLine ;
}
return result;
}
By the way if you're wondering why your numbers are't random try creating only one Random object. You can then use it as you're doing now.

Cause you are printing the type itself which calls it's default ToString() instead you should do call PrintMatrix() on every object instance. As well consider giving a better name to your type than Object since that's a built-in type
foreach(Object item in conteiner)
{
item.PrintMatrix();
}

Related

Using the value in one array to set the object in another

I am stuck trying to figure out how to use the values of one array of numbers to initialize a second array of objects. This might not be the most effective way to do something like this in a real program, but I am just trying to understand how to create a relationship between two different arrays.
The first array is just a randomly generated array holding values 0,1 or 2. The second array is an array of Occupant objects. Each occupant has an occupant id that will be either 0, 1 or 2. I am trying to generate the second array of occupants by copying the values of first array and then initializing the second based on the occupant id.
Nothing I have tried will compile, and I can't think of anything else on my own except writing a million if statements. Surely there must be a simple solution I am missing. Any help you can offer will be greatly appreciated.
FYI: Occupant is the base class, three classes derive from it, each with a unique id number.
static public class Board
{
static public Occupant[,] board = BoardGen();
static private Occupant[,] BoardGen()
{
Random myRandom = new Random();
int[,] setup = new int[10, 10];
for (int i = 0; i < setup.GetLength(0); i++)
{
for (int j = 0; j < setup.GetLength(1); j++)
setup[i, j] = myRandom.Next(0, 3);
}
Occupant[,] populate = new Occupant[10,10];
// How to link setup to populate using the number to choose an occupant based on it's id number?
return populate;
}
}
}
I would suggest to fill-in the second table along with the first, or even better, completely forget about the first table:
static private Occupant[,] BoardGen()
{
Random myRandom = new Random();
// Not needed
// int[,] setup = new int[10, 10];
Occupant[,] populate = new Occupant[10, 10];
for (int i = 0; i < populate .GetLength(0); i++)
{
for (int j = 0; j < populate .GetLength(1); j++)
{
int randomSetup = myRandom.Next(0, 3);
switch (randomSetup)
{
case 0:
populate[i, j] = new Occupant_0(); // Derived Class with id=0
break;
case 1:
populate[i, j] = new Occupant_1(); // Derived Class with id=1
break;
case 2:
populate[i, j] = new Occupant_2(); // Derived Class with id=2
break;
default:
break;
}
}
}
return populate;
}
abstract class Master
{
public abstract int Id { get; }
}
class A : Master
{
public override int Id => 1;
}
class B : Master
{
public override int Id => 2;
}
class C : Master
{
public override int Id => 3;
}
Type[] types = new Type[] { typeof(A), typeof(B), typeof(C) };
int[] yourIds = new int[100];
Master[] generated = new Master[yourIds.Length];
for (int i = 0; i < yourIds.Length; i++)
{
generated[i] = (Master)Activator.CreateInstance(types[yourIds[i] - 1]);
}
I cannot understand your question completely, but this logic should fit your situation.
The point is that you can create an instance in runtime with the System.Activator and a System.Type.

How can I add objects Cbook to my class CBooks without using lists

Cbooks has an atribute "CTeam[] Teams" and it is of fixed size (8). If I want to add objects to it using this in the Main:
CBook A1 = new CBook("Title1", "Author1");
CBook A2 = new CBook("Title1", "Author2");
CBooks ArrayOfBooks = new CBooks(8);
ArrayOfBooks.Add(A1);
ArrayOfBooks.Add(A2);
then position 0 and 1 are ocuppied, and the positions from 2 to 7 are null. What I want to do is, using a variable "int aux=0", count the ocupied positions like this:
for (int k = 0; k < NumberOfTeams; k++)
{
if (Teams[k].Name=="")
Aux += 1;
}
So, Aux in this case would be 2, then I want to do "Teams[Aux] = A" so that A would be in the position 2 and now I should have three objects in my array. But I'm getting "Index out of bound"
Your implementation then should look similar to this:
public class Program
{
public static void Main(string[] args)
{
Element a = new Element("A");
Element b = new Element("B");
MyArray array = new MyArray(8);
array.Add(a);
array.Add(b);
Console.WriteLine(array.Count()); //2 Elements are in the array
}
}
//Sample element class.
public class Element{
public readonly String MyString;
public Element(String myString){
MyString = myString;
}
}
//Sample array class.
public class MyArray{
private readonly Element[] myArray;
private int count; //Use a property here
public MyArray(int size){
//Be careful -> check if size is >= 0.
myArray = new Element[size];
}
public bool Add(Element element){
if(myArray.Length == count) // return false if no more elements fit.
return false;
myArray[count] = element;
count++;
return true;
}
public int Count(){
return count;
}
}
So there is no need for creating an extra count loop. Your "count" variable in "MyArray" class holds always the correct value.
Anyway the implementation or use case of this code is a little bit clunky.
Why are you cant use directly a more safe list or something. That would be a better solution.
What do you need CBooks for? From what I understand, it's just an array of 8 CBook objects so why not use CBook[]?
CBook A1 = new CBook("Title1", "Author1");
CBook A2 = new CBook("Title1", "Author2");
CBooks[] ArrayOfBooks = new CBook[8];
ArrayOfBooks[0] = A1;
ArrayOfBooks[1] = A2;
int aux = 0;
for (int k = 0; k < ArrayOfBooks.Length; k++)
{
//break the loop because we know there are no more books
if (ArrayOfBooks[k] == null)
break;
aux++;
}
The question doesn't cover what the variables NumberOfTeams and Teams are for but could those be added to the implementation of CBook?

Write an array to a file in c#

I am trying to write an array to a file with C# and am having issues.
I've started learning c# the last few days and now can't figure out why this happens.
namespace Arrays
{
class Program
{
static void Sort()
{
}
public static void Random()
{
int[] test2 = new int[5];
int Min = 1;
int Max = 100;
Random randNum = new Random();
for (int i = 0; i < test2.Length; i++)
{
test2[i] = randNum.Next(Min, Max);
Console.WriteLine(test2[i]);
}
Console.WriteLine("");
for (int ii = 0; ii < test2.Length; ii++)
{
Array.Sort(test2);
Console.WriteLine(test2[ii]);
}
String writeToText = string.Format("{0}", test2);
System.IO.File.WriteAllText(#"C:\\Users\\hughesa3\\Desktop\\log.txt", writeToText); // Writes string to text file
}
static void Main(string[] args)
{
Random();
}
}
}
It generates a random 5 numbers and puts it into the array, When I try to write this to a file it prints System.Int32[]
I understand that because im trying to print a formated string but how would i go about printing each int ? I've tried using a loop but it will only save the last int as i put it inside the loop?
Can anyone give me some advice ?
Thanks
Use WriteAllLines and pass string array as input.
System.IO.File.WriteAllLines("filename", test2.Select(i=>i.ToString()).ToArray());
or, if you want to write in , separated form use this.
System.IO.File.WriteAllText("filename", string.Join(",", test2.Select(i=>i.ToString()).ToArray());
The problem is that String writeToText = string.Format("{0}", test2); calls ToString method of the test2 array and it returns System.Int32[]
Change it to
String writeToText = string.Join("", test2.Select(x=>x.ToString())
or
String writeToText = string.Format("{0}", test2.Select(x=>x.ToString().Aggregate((c,n)=>string.Format("{0}{1}", c,n))
//Add this method and use in System.IO.File.WriteAllText(#"C:\\Users\\hughesa3\\Desktop\\log.txt", ArrayToString(test2));
public static String ArrayToString(int[] arr)
{
return arr.Aggregate("", (current, num) => current + (num + " "));
}

How to minus data length inside the index of a list, if the index is an array?

Well, first of all, I am not sure whether my title in this question delivered what I want to ask or not. I just do not sure how to describe my problem in one sentence, hopefully the title would not cause any misleading.
If I have a list. Inside the list contain 100 data : list<100>
If I put this list inside a 1 second timer tick and do like this:
myList.RemoveRange(0, 2);
This mean, every 1 second, the data length inside the list will be -2;
This mean, every 1 second, it will be <98> , <96> , <94> .... <0>
Now my problem is...I still have a list, but the list will contain an array: list<array[100]>
Now, what I want is, every 1 second, the data length inside the array inside the list will be -2. But I am not sure know how to do this...
what I want is, every 1 second <array[98]> , <array[96]> , <array[96]> ... <array[0]>
And so, if the list contain <array0[100] , array1[100], array2[100]>
if i put this list inside a loop, every 1 second, it should be
array0[98] , array0[96] ... array0[0]
array1[98] , array1[96] ... array1[0]
array2[98] , array2[96] ... array2[0]
Update:
List<int[]> myList = new List<int[]>();
object myLock = new object();
Random rand = new Random();
public Form1()
{
timer1second.Start();
}
private void SomeMethod()
{
int[] myData = new int [100]
for (int i = 0; i < 100; i++)
{
//generate some random number to store inside myData[]
myData[i] = rand.Next(1 , 10);
}
lock (myLock)
{
myList.Add(myData); //mean List[0] = myData[100]
}
}
private void timer1second_Tick(object sender, EventArgs e)
{
lock (myLock)
{
//do something here in myList to get the myData[100 - 2]
//so that every 1 second tick, the data length inside the MyData will be -2
}
}
Convert the Array item into a List.
Then remove the range from the List
Convert it back to an Array.
Insert it back into the List
Here is a sample:
int currentIndex = 0;
var myList = new List<int[]>();
var intArray = new int[100];
myList.Add(intArray);
// Convert to List.
var newIntArrayList = myList[currentIndex].ToList();
// Remove the ranges
// Index would be based on you logic
newIntArrayList.RemoveRange(0, 2);
//Replace the list with the new arry
myList[currentIndex] = newIntArrayList.ToArray();
Update : Array.Resize should also help.
int currentIndex = 0;
int arrayLength = 100;
var myList = new List<int[]>();
var intArray = new int[100];
myList.Add(intArray);
// Get the array
var array = myList[currentIndex];
// Resize
Array.Resize(ref array, arrayLength-2);
//Replace the list with the update array
myList[currentIndex] = array;
List<int> myList = new List<int>();
for (int i = 1; i < 101; i++)
{
myList.Add(i);
}
for (int i = 100; i > 0; i--)
{
System.Threading.Threading.Sleep(1000);
myList.RemoveAt(i);
i -= 1;
myList.RemoveAt(i);
}
Resizing lists and arrays is an expensive operation. Would you consider a custom data structure for your needs with convinient interface and optimized underlying structure? So every tick you will only increment and integer value representing offset:
class Data
{
const int Step = 2;
List<int[]> data;
List<int> cursors;
public Data()
{
data = new List<int[]>();
}
public void AddArray(int[] array)
{
data.Add(array);
cursors.Add(array.Length);
// or cursors.Add(0), depending on your needs
}
public void Tick()
{
for (int i = 0; i < cursors.Count; i++)
{
cursors[i] -= Step;
// or cursors[i] += Step, depending on your needs
}
}
public IEnumerable<int> GetValuesAtIndex(int index)
{
for (int i = 0, i < data[index].Length; i++)
{
if (i > cursors[index]) // or i < cursors[index]
{
yield return data[index][i];
}
}
}
}

Changing one element of an array changes others

I have the following piece of code:
Chromosome[] pop = new Chromosome[popSize];
int[] initialGenes = new int[i];
for (int m = 0; m < i; m++)
initialGenes[m] = -1;
for (int j = 0; j < popSize; j++)
{
pop[j] = new Chromosome(graph, initialGenes);
}
Chromosome is my class and has a property
public int[] Genes { get; set; }
As you can see I initialize an array of Chromosome objects. The problem is when I try to change the value of pop[i].Genes[k] (e.g. pop[1].Genes[2] = 123) all Genes[k] of pop are changed (i.e.
pop[0].Genes[2] == 123
pop[2].Genes[2] == 123
etc.)
Could anyone explain what the problem is?
Thanks.
Change your constructor of Chromosome to make a copy of the array that is passed in.
I assume, your constructor looks like this:
public Chromosome(int[] initialGenes)
{
Genes = initialGenes;
}
But it should look like this:
public Chromosome(int[] initialGenes)
{
Genes = new int[initialGenes.Length];
Array.Copy(initialGenes, Genes, Genes.Length);
}
This happens because you pass same object to all Chromosome clases. You should create new copy of initialGenes for each Chromosome class

Categories

Resources