Question
I need a data structure like the above in C# but I am having problems accessing the contents, I have seen that I can do this in C++ how is the same done in c#?
List<Dictionary<string, List<int>>> data =
new List<Dictionary<string, List<int>>>(5);
when i do Data[0] i get an error stating index out of bounds..
Can anyone point me as to how I can do this. or what I am doing wrong ?
Addendum:
->What im trying to do
I am basically creating a data structure which keeps a plan of the month.
So a List of the 5 weeks each containing->
a Dictionary of activities, where the value for each activity is a ->
list of 7 integers representing the hours spent each day of the week on that activity.
I have got that I need to add blank entries.
Additional Question is like this.
->Query
Right now I will have to Add 5 blank dictionaries to the list.
and a list of 7 integers(initialized to zero) in each Key of the dictionary representing each days time consumed.
Is there a way to initialize 5 blank dictionaries in the list and same inside, without manually creating new dictionaries and adding them.
With c++ i believe that you can do this and even enter the value to which you want to initialize each entry to be, so..
A statement like
Vector<int> *vec = new Vector<int>(5,0);
Initialized the vec with 5 entries each being 0. Can I do the same in c# ?
Thanks for the help.
This has nothing to do with the list being a complex type. You'll get the same thing with this:
List<string> list = new List<string>(5);
string x = list[0]; // This will fail too
The List<T>(int) constructor creates a list with the given capacity (i.e. the array backing it will have an initial size of 5, assuming it doesn't decide that's just too small to be useful). It still has a size of 0.
You still need to add elements to the list before you can access them.
EDIT: There's no constructor to "fill" a list with a given set of values. With LINQ you could write:
List<string> list = Enumerable.Repeat("foo", 5).ToList();
... but you wouldn't want to do that for your dictionary one, as otherwise you'll end up with 5 references to the same dictionary. You could use:
var list = Enumerable.Range(0, 5)
.Select(x => new Dictionary<string, List<int>>())
.ToList();
Note that each dictionary here is empty though.
Personally I'd probably just create the list and fill it with a for loop though...
You have initialized the List with a default size of 5, but the list is still empty, thus when you attempt to access index 0 in the data object, it is out of bounds, because the current amount of items in the list is 0, thus there is no objects to access.
if you add a new item to data, with data.Add(...) you can access the object at the first index with data[0]
Related
Currently I'm working on a project using LinqtoSql and I would like to get an simpler solution for my current problem.
Example:
Lets say I got a table named Example with three rows (with values 1,2,4)
Now in code(c#) I got these values as a list of Integer(lets name it lstExisting)
Now in my method I got another List of Integer ( say lstCurrent) with Integers values (1,2,3)
Now I want to compare the both the list and find the difference of integers and update the database, so according to my example a new row with value 3 should be added and the existing row with value 4 should be deleted.
PS:(the integer values will be always unique and will be 1,2,3,4)
Linq solutions will be preferable but I don't mind other easier solutions.
Thanks
You need to find new items and to be deleted items using Except like:
var newItems = lstCurrent.Except(lstExisting).ToList();
var toBeDeletedItems = lstExisting.Except(lstCurrent).ToList();
Later you can iterate each list and Add/Delete accordingly.
Try using Contains(). With having two lists, you can write something like this. What this does is it iterates over each item in your methods list and checks the original to see if its there.
var lstExisting = getExistingList();
var lstCurrent = getCurrentList();
foreach(var currentInt in lstCurrent)
{
if(!lstExisting.Contains(currentInt))
{
//insert currentInt
}
I have a List<> in c# contains number of objects, for example 100. I need to select some objects in a row without repetition. For example, I select object 4 and then randomly a random number of sequential objects after that (object 5 and 6). When I want to select another collection, it shouldn't contains object 4, 5, and 6. If I remove these objects from List then sometimes I will receive object 2,3,7,8 that useless. In another words, I need some sub lists from main list without repeated objects and with the same order as main list. I was wondering if anybody help me to solve this algorithm.
You can store your objects in a Dictionary so you can keep an extra information for each object, in your case a boolean that tells you if your object has been selected or not, something like that :
//initializing the dictionary, any item has been selecte
Dictionary<object,bool> dic = list.ToDictionary(e => e, e => false);
and any time you select an item you change the boolean value to true :
dic[selectedObject] = true;
and when you try to select a new item from your dictionary you only have to skip the key/value pairs having a true value.
I've always thought the any index should be unique, but I think it's not true at least for SQL Server as shown in the following post:
Do clustered indexes have to be unique?
Recently I had to store a very amount of data within a collection and thought of using a dictionary for it's the fastest collection to get an object by index. But my collection would have to allow duplicated keys. But in fact duplicated keys would not be a problem since any of the object returned would be meet the requirements (The objects are not exactly unique, but the keys would be).
Some more research led me to the following post:
C# Hashset Contains Non-Unique Objects
Which shows a way to get a HashSet with "duplicated keys". His problem would be my solution but I wonder if there's any other way that I can have a list with duplicated keys which allows me to search very fast without having to do any workaround the get this done.
"duplicated indexes would not be a problem since any of them would be meet the requirements"
If by this, you mean that obtaining any item stored against the same index value would be satisfactory you when retrieving an item by index, then a simple Dictionary will suffice.
E.g.
Dictionary<int, string> myData = new Dictionary<int, string>();
myData[1] = "foo";
myData[2] = "bar";
myData[2] = "baz"; // overwrites "bar"
var myDatum = myData[2]; // retrievs "baz" not "bar", but this is satisfactory.
I would like to create a list variable of items from another list. So lets say I have a list of 100 items I would like to pull items 25 - 35 and put them inside of another list. is there a way of doing this without calling a big for statement and pulling out the element one by one and putting that into a list.
you can use .Skip and .Take from System.Linq ....
Like this:
var result = myList.Skip(24).Take(10);
and if you need use ToList on the result to get another list
For a List<T>, you can use the GetRange Method.
Creates a shallow copy of a range of elements in the source List(Of
T).
Do note that the second argument represents the count of elements in the range, not the end-index of the range.
Since you mention ArrayList, I should point out that while it too has a GetRange, method, the type is considered essentially legacy since .NET 2.0.
Use both Take and Skip
var newList = oldList.Skip(25).Take(10);
Anyone know how to select a certain amount of items in a List to bind to a DataSource? Basically I'm getting back 10 items (which I don't have control over) and I only need to show 5. Originally I was thinking of using a loop and adding 5 items to a new list but that seems like a lot of code. Is there an expression that I can use to select the first 5?
//Returns a List<DataItem>
MyDataListControl.DataSource = Helper.GetDataItems(); //<= Possible expression?
You may take a look at the Skip and Take LINQ extension methods. So in your case if you wanted to take only the first 5 elements of some IEnumerable<T>:
MyDataListControl.DataSource = Helper.GetDataItems().Take(5).ToList();
What about List's GetRange method? Have you tried that? I don't the internal workings of the method; whether it also creates a new list or not.
GetRange(int index, int count)
Here is the msdn link for it.
RemoveRange will probably be best as you won't have to instanciate a new list, unless that happens internally anyway.. Just make sure you're always getting 10 items or you'll potentially get an ArgumentOutOfRangeException.
list.RemoveRange(5, 5);
That should leave you with the first five items.