Array of HashSets with comparer in C# - c#

as the title says, i have an array of hashsets, but i don't know how apply to them a comparer. Like this:
//This Works:
public HashSet<Animal.AnimalCell>UpdateList = new HashSet<Animal.AnimalCell>(new CellComparer());
//This Does not work:
public HashSet<Animal.AnimalCell>[]UpdateListThreaded = new HashSet<Animal.AnimalCell>(new CellComparer())[10];
//This Does not Work :
public HashSet<Animal.AnimalCell>[]UpdateListThreaded = new HashSet<Animal.AnimalCell>[10](new CellComparer());
//This Works:
public HashSet<Animal.AnimalCell>[]UpdateListThreaded = new HashSet<Animal.AnimalCell>[10];
Of Course i need the comparer.. What am i doing wrong?
Thank you

You have an array of HashSet<T>, you need to initialize each element in the array:
for (int i = 0; i < UpdateList.Length; i++)
{
UpdateList[i] = new HashSet<AnimalCell>(new CellComparer());
}

Related

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?

Using GetEnumerator for Dictionary initialization C#

I have a class Cluster.cs defined as:
public class Cluster
{
protected int _clusterID = -1;
private static int _clusterCount = 0;
protected int _attributeCount;
// _clusterObjects contains EvoObjects in this cluster.
protected List<EvoObject> _clusterObjects = new List<EvoObject>();
/** _nkA[_i] is the total occurrences of the attribute _i in this cluster*/
protected Int32[] _nkA;
// For each attribute, record their values as KeyValuePair.
protected Dictionary<Int32, UtilCS.KeyCountMap<Int32>> _attributeValues = new Dictionary<Int32, UtilCS.KeyCountMap<Int32>>();
public Cluster(int _clusterID, int _attributeCount)
{
this._clusterID = _clusterID;
this._attributeCount = _attributeCount;
_nkA = new Int32[_attributeCount];
}
// Initialize _attributeValues
IEnumerable<Int32> _range = Enumerable.Range(0, _attributeCount).GetEnumerator(_i => {_attributeValues[_i] = new UtilCS.KeyCountMap<Int32>()});
}
while initializing _attributeValues, I got error as:
"No overloaded method for GetEnumerator takes 1 argument"
whereas I've only 1 argument to initialize i.e. _attributeValues which is actually a dictionary that's why have to enumerate at it.
Also if I declare _attributeCount static, I'm unable to use it in constructor and if I declar it non-static, I'm unable to use it Range method of Enumberable.
How will I initialize _attributeValues then?
How to declare _attributeCount static or non-static?
It looks like your trying to initialize the Dictionary by using a variable (_range) that is set at object creation. This should be moved into the constructor. It appears you are attempting to create three new attributes with keys 0,1,2 and values of new UtilCS.KeyCountMap().
If this is correct, then I would suggest using this as your constructor.
public Cluster(int _clusterID, int _attributeCount)
{
this._clusterID = _clusterID;
this._attributeCount = _attributeCount;
_nkA = new Int32[_attributeCount];
for (var i = 0; i < 3; i++)
{
_attributeValues.Add(i, new UtilCS.KeyCountMap<int>());
}
}
However, since you are sending in _attributeCount I would say you could use that instead of 3.
public Cluster(int _clusterID, int _attributeCount)
{
this._clusterID = _clusterID;
this._attributeCount = _attributeCount;
_nkA = new Int32[_attributeCount];
for (var i = 0; i < _attributeCount; i++)
{
_attributeValues.Add(i, new UtilCS.KeyCountMap<int>());
}
}
Enumerable.Range(0, _attributeCount).ToList().ForEach(x => _attributeValues.Add(x, new UtilCS.KeyCountMap<Int32>()));

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

Dynamic Initialize in c#

I've a class
class sampleClass
{
...........
...........
public sampleClass()
{.........}
}
and in another class i created an array like
sampleClass[] X=new sampleClass[]{new sampleClass(),new sampleClass()}
here i gave 2 instance of the constructor. i need this dynamically..
that is the size of the array should be dynamically changed
It sounds like you want something like:
int size = // whatever
SampleClass[] array = new SampleClass[size];
for (int i = 0; i < size; i++)
{
array[i] = new SampleClass();
}
EDIT: If you really want to avoid a for loop, you could do something like:
SampleClass[] array = Enumerable.Range(0, size)
.Select(x => new SampleClass())
.ToArray();
... but I don't think that's actually better than using a loop.
This is just a syntactic sugar, you can gain the same using your own code:
sampleClass[] X = new sampleClass[num];
for(int i = 0; i < num; i++)
{
X[i] = new sampleClass();
}
You can initialize the array using a loop:
sampleClass[] X = new sampleClass[123];
for (int i = 0; i < X.Length; ++i)
X[i] = new sampleClass();
If your class was a value type the array is initialized when it is allocated:
struct sampleStruct { ... }
sampleStruct[] X = new sampleStruct[123];
// No need to initialize every array cell.
However, using a struct instead of a class is not something you should do simply to avoid a loop. You can read more about value types on MSDN.

How to initialize an array of arrays (or jagged array) using CodeDom?

I'm trying to use CodeDom to generate C# (.Net 2.0) code that would do the following:
int[][] myArray = new int[someSize][];
In CodeDom, initializing an array requires a CodeArrayCreateExpression. The MSDN says:
If a language allows arrays of arrays, it is possible to create them by nesting a CodeArrayCreateExpression within a CodeArrayCreateExpression.
The way I understand it, the only possibility is to write something like this:
// Declaration and initialization of myArray
CodeVariableDeclarationStatement variable =
new CodeVariableDeclarationStatement("System.Int32[][]", "myArray",
new CodeArrayCreateExpression("System.Int32[][]",
new CodeExpression[] { new CodeArrayCreateExpression("System.Int32[]", 0) }));
But this generates this:
int[][] myArray = new int[][] { new int[0] };
That's not perfect but I could do with it if I knew the size of myArray at generation time, which I don't.
I could write a function that does the initialization and call it in CodeDom but it would be nicer if I could do it in pure CodeDom. Did I miss something ?
[EDIT] Background information
The idea is to automatically generate an adapter between two object representations. I have a meta-description (some kind of IDL) saying: "I have a container object which has a field of type int[][]" and two representations of this container:
// Internal representation
public class InternalContainer {
int[][] myArray;
}
// Network representation
public class NetworkContainer {
int[][] myArray;
}
Thus the question of generating code that can adapt to any size of array.
You have the following workaround to create a jagged array with a dynamic length:
Create the dom equivalent of
ELEMENTTYPE[] array = (ELEMENTTYPE[])Array.CreateInstance(typeof(ELEMENTTYPE), length);
ELEMENTTYPE can be any type, be it an array or not.
Here's my solution, using a CodeSnippetExpression
public static DOM.CodeExpression NewArray (this Type type, int dim, int size) {
string dims = String.Concat(Enumerable.Repeat("[]", dim - 1).ToArray());
return new DOM.CodeSnippetExpression(string.Format("new {0}[{1}]{2}", type.FullName, size, dims));
}
CodeArrayCreateExpression CodeArrayCreateExpression(Array array)
{
CodeArrayCreateExpression arrayCreateExpression = new CodeArrayCreateExpression(array.GetType(), array.GetLength(0));
if (array.GetType().GetElementType().IsArray)
{
CodeArrayCreateExpression[] values = new CodeArrayCreateExpression[array.GetLength(0)];
for (int j = 0; j < array.GetLength(0); j++)
{
values[j] = this.CodeArrayCreateExpression((Array)array.GetValue(j));
}
arrayCreateExpression.Initializers.AddRange(values);
}
else if(array.GetType().GetElementType().IsPrimitive)
{
CodeCastExpression[] values = new CodeCastExpression[array.GetLength(0)];
for (int j = 0; j < values.Length; j++)
{
values[j] = new CodeCastExpression();
values[j].Expression = new CodePrimitiveExpression(array.GetValue(j));
values[j].TargetType = new CodeTypeReference(array.GetType().GetElementType());
}
arrayCreateExpression.Initializers.AddRange(values);
}
return arrayCreateExpression;
}

Categories

Resources