Looking for a better multi-key solution - c#

So I've looked at Dictionaries and various arrays for this, and I'm sure I'm missing an elegant solution.
Currently, I have a configuration dictionary that has information about what data needs to be retrieved.
Then I create a string[,] array where the first string is the item number and the second is the configuration value for a given item, then the value is the value for that configuration item. Something like this:
ret[0,0] = "12345678"
ret[0,1] = "\\localhost\images"
ret[0,2] = "\test.img"
ret[1,0] = "23231231"
ret[1,1] = "\\localhost\images"
ret[1,2] = "\here.img"
There are more values, but that's the gist of it.
Now I need to also to grab each of those .img files (which are concatenated TIFF files) and extract images into byte[] values. Some of the additional values are an offset and length in the file for that item number's image, so extracting the images is easy. For some reason, however, I'm having a hard time finding a smart way to index the byte[] arrays for a given image (there's a front and a rear image for each) with the index value of the ret[,] array. Neither Dictionaries or Lists seem like they'd work. If I could have a jagged array with mixed values, that would work, but I don't really see how to do that.
Please let me know if I'm not making sense regarding what I'm looking for. I may need to draw it out lol
Thanks!

You need something like:
Dictionary<int,Dictionary<int,<string>> myVar = new Dictionary<int,Dictionary<int,string>>();
myVar.add(0,new Dictionary<int,string>(0,'string'));
Console.WriteLine(myVar[0][0]);
You might also want to check the DataTable class.

You can simply define your own class for the image.
It stores the number, and all the other strings and the byte array. Then you implement a List of this class.

Related

How to create an array without knowing how many values will be store?

In C# I'm storing values in an array.
So to create this array I'm using this code, 'int[] values = new int[10];'
But, what if I need more than 10 values, or in the case I never know how many values I will have. Could be 1, 10 or 100.
I understand the idea that I need to let the compiler know how big the array should be so it can allocate memory space for it.
Is there a way to work around that?
You could just use a List and let it do all the heavy lifting for you:
List<int> values = new List<int>();
Arrays must have defined length. If you want dynamic size, consider using List class.
Please take a look at and research the concept of "Immutable objects"
An array has a fixed size, If you need an array with a dynamic size it is best to either create extension methods or a handler that does the work for you.
The work to be done is to get the array, create a new array with the new size based on whether you want to add or remove something, and to populate the new array with the data from the previous array. This will create a new object instead of modifying the previous object and will make sure you don't push items to a full array, or have an array with a size larger than the items that fit in it.
Ofcourse the List class would work as well and would probably solve your problem.

Grouping neighbouring entries with the same value in a 2d array

EDIT: I now realized the question was not appropriate for stack but I've gotten a lot of helpful advice anyway. Thanks everyone!
I have a 2d array and I want to group together neighbors of the same value. Using C# (working with unity).
Let's say I have this:
int[,] array {
0,0,0,0,0,0,1,0,0,0,
0,1,1,0,0,0,1,0,0,0,
0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,0,
0,0,0,0,0,0,1,1,1,0
}
There are three "clusters" of 1:s. I want to add them to a dictionary with some variable for identification. So maybe first add the neighboring values to a list, add that list to a dictionary, clear the list and move onto the next cluster.
The columns and rows would be of equal length in the real thing.
I would also want the sorting method to accept arrays of various sizes so no hardcoded values. I parse the array from an XML document.
I've tried looking into Array.Sort but the resources I have found have been exclusively about sorting values in as/descending order. Just pointing me in the right direction, some some relevant web resources would be greatly appreciated!
I'm not going to give you the answer in full code since 1. you shouldn't be asking for it here and 2. you can definitely work it out yourself.
This is a good opportunity for you to whip out your pen and paper and figure out the algorithm. Lets say we want something similar to your task: just grouping the clusters of ones. The pseudocode might look like this.
Create a list of clusters
For each element in the grid, check if its a one.
If it is a one, check if it has a neighbor that is part of a cluster.
If so, add it to that cluster, else create a new cluster an add it.
If would then run through this on paper with a small example.
Once you have your desired algorithm, putting it into a dictionary and sorting it should be trivial.

How to Jagged List C#

I am trying to create a jagged array but due to the dynamic-ness of the data I am working with I do not want to waste resources creating a a large jagged array.
I am currently doing:
int[][][] data = new data[Int16.MaxValue][][];
I do not how big the data set is, or is there a better way than doing it via Lists?
Yes, you should use List<T>.
In this case, you would use List<List<List<int>>>.
Your array:
int[][][] data = new data[Int16.MaxValue][Int16.MaxValue][Int16.MaxValue];
will take up (2^16)^3 = 2^48 = way more storage space than you have,
not to mention that that declaration is not valid C#.
If you don't know how much space you need when you initialize, then it would be best to use a dynamically resizing list.
Use a variable similar to this:
List<List<List<int>>> data = new List<List<List<int>>>();
This variable allows you to add List<List<int>>'s to it, and those lists contain List<int>'s, which of course contain int's
If you absolutely do not want to use Lists, you can always replicate what Lists do under the hood: Create your array with a small number of elements, and when you reach the maximum, create a new array that is double the original's size, copy your existing array into it, and dispose of your original. Continue this pattern until you are done. I recommend using Lists instead, but this is how you would get around it if, for some reason, you just don't want to use Lists.
In fact, you can create jagged arrays without defining second and further dimensions.
int[][][] jagged = new int[256][][];
But at large datasets it is more effective to use streaming data - i.e., combinations of IEnumerable<T>.

How can I read a CSV file into a System.Array that has already been initialized?

I want to create an array and initialize it with for example for testing:
string[] myList= new string[]
{ "item1",
"item2",
}
If later I want to fill it from a csv file, will I be able to add any number of items to it ?
I don't want to use dynamic array because initialization syntax with .add method is not as convenient when I have to do it by hand.
Arrays have a fixed size, so you will not be able to add any amount of numbers to it. The closest thing you can do is to create an array that is large enough to store the amount of numbers you will be most likely generating but this is highly inefficient and also prone to errors if you generate more numbers than you have initially anticipated.
You will have to use a dynamic data structure such as an ArrayList, you might not find it convenient but it is much easier and makes you code look neater and more efficient.
no , you can not add multiple items.
What is the problem with List< string>

Array of an unknown length in C#

I've just started learning C# and in the introduction to arrays they showed how to establish a variable as an array but is seems that one must specify the length of the array at assignment, so what if I don't know the length of the array?
Arrays must be assigned a length. To allow for any number of elements, use the List class.
For example:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
Use List<> to build up an 'array' of unknown length.
Use List<>.ToArray() to return a real array, and not a List.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
A little background information:
As said, if you want to have a dynamic collection of things, use a List<T>. Internally, a List uses an array for storage too. That array has a fixed size just like any other array. Once an array is declared as having a size, it doesn't change. When you add an item to a List, it's added to the array. Initially, the List starts out with an array that I believe has a length of 16. When you try to add the 17th item to the List, what happens is that a new array is allocated, that's (I think) twice the size of the old one, so 32 items. Then the content of the old array is copied into the new array. So while a List may appear dynamic to the outside observer, internally it has to comply to the rules as well.
And as you might have guessed, the copying and allocation of the arrays isn't free so one should aim to have as few of those as possible and to do that you can specify (in the constructor of List) an initial size of the array, which in a perfect scenario is just big enough to hold everything you want. However, this is micro-optimization and it's unlikely it will ever matter to you, but it's always nice to know what you're actually doing.
You can create an array with the size set to a variable, i.e.
int size = 50;
string[] words = new string[size]; // contains 50 strings
However, that size can't change later on, if you decide you need 100 words. If you need the size to be really dynamic, you'll need to use a different sort of data structure. Try List.
Use an ArrayList if in .NET 1.x, or a List<yourtype> if in .NET 2.0 or 3.x.
Search for them in System.Collections and System.Collections.Generics.
You might also want to look into Dictionarys if your data is unique, This will give you two columns to work with.
User name , Total bill
it gives you a lot of built in tools to search and update just the value.
var yummy = new List<string>();
while(person.FeelsHappy()) {
yummy.Add(person.GetNewFavoriteFood());
}
Console.WriteLine("Sweet! I have a list of size {0}.", list.Count);
Console.WriteLine("I didn't even need to know how big to make it " +
"until I finished making it!");
try a generic list instead of array
In a nutshell, please use Collections and Generics.
It's a must for any C# developer, it's worth spending time to learn :)
As detailed above, the generic List<> is the best way of doing it.
If you're stuck in .NET 1.*, then you will have to use the ArrayList class instead. This does not have compile-time type checking and you also have to add casting - messy.
Successive versions have also implemented various variations - including thread safe variants.
If you really need to use an array instead of a list, then you can create an array whose size is calculated at run time like so...
e.g i want a two dimensional array of size n by n. n will be gotten at run time from the user
int n = 0;
bool isInteger = int.TryParse(Console.ReadLine(), out n);
var x = new int[n,n];

Categories

Resources