Find solution for an algorithm - c#

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.

Related

Insert into ObservableCollection per int comparison

Say I have an ObservableCollection with two items:
0: dateUnix: 333
1: dateUnix: 222
Now I want to add a new Item:
dateUnix: 300
If I just were to use the .add() method, the item would get added at the end. But I want the item to be inserted between 222 and 300 since this would make the list sorted.
How do I insert an item at a certain position where it is less then item value after and higher then item value before?
Of the top, I can think of two ways of doing this.
One would be, as was pointed out in the comments, to just insert and sort afterwards.
Another, more complex and more rewarding way would be to find the index of the first item greater or lesser than the one you're inserting and insert it at that index. Your list seems to be sorted in descending order, so it'd need to be the first lesser than.
You could achieve this using LINQ:
ObservableCollection<Int> collection = new ObservableCollection(new List<int>{333,222}); // == [333,222]
Int toInsert = 300;
collection.Insert(collection.IndexOf(collection.First(elem => elem < toInsert)), toInsert); // output == [333,300,222]
See this Fiddle for a working example.
If your collection is already sorted, just find the appropriate index to insert the element at (either via a linear or the faster binary search) and use Insert to store the element at that specific index.

Looking for an alternative to iterating thru layers of lists

This is a .Net C# program. Here is what I have, and it works, but is slow:
The outside collection has a list of records with a key, there are approximately 5500 values
The next collection has a list of accounts that exist for the key across all groups, there are approximately 5 to 10 values
The next collection has a list of groups that are required for the key, there are three groups (but they vary, so its not a constant list)
I need to figure out what adds need to happen. An add would be if one of the groups does not exist or if it is missing any of the accounts.
I start off with a list of existing keys/groups/accounts.
Currently I am using something like this:
foreach (rec in keysList)
foreach (account in accountsList)
foreach (group in groups)
if (!existing.contains(keys/groups/accounts))
add record
This is slow and seems like there should be an alternative to the multi-layer nesting.
Thanks,
Sammer
You need to use the HashSet<T> correctly in order for it to perform as expected. Use HashSet<T>.Contains(T key).
The problem you must solve is, your key type must implement (correctly) IEquatable<Key>, or you must pass in a custom instance of IEqualityComparer<Key> to the HashSet constructor.
You can flatten the list first:
var list = keyList.SelectMany
(
k => k.SelectMany
(
a => Select
(
g => new
{
Group = g,
Account = a,
Key = k
}
)
)
);
Once your structures are in flat lists, the rest is easy:
var difference = list.Except(otherList);
foreach (var d in difference)
DoAdd(d.Key, d.Account, d.Group);
Note that anonymous types compare by value, not by reference (it compares all the individual properties, not the single object reference), so flattening the list into anonymous types also takes care of difficulty caused by difference references to the same data.

Compare List of Integers and add/remove the rows in database using the difference in result LinqtoSQL

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
}

How to sort List within another list using linq in vb.net

I have 2 generic lists.
Dim Item As New List(Of String)
Dim Item2 As New List(Of Array)
Item conatains 4 elements.
They are 1. Item code
2. Description
3. BIN
4. Price
But they are just entered sequentially
For example
Item={5858545, HairDryer, A45, 50}
There are many Item and Item 2 contains The list of Items.
For example Item2= {{5858545, HairDryer, A45, 50},....}
Now i want to sort the Item2 according to according to the BIN and then By Item code
So now my list Item2 will contains elements of Item sorted according to BIN and then By Item code.
How to do this with LINQ or any other way?
Thanks
You shouldn't be storing objects as an array or list of values. Create a new class to represent your item. Give it four properties for BIN, name, etc., and then create a list of that custom type.
To order the list you can use the OrderBy method, followed by the ThenBy method. It will read much better if you have a custom object, as it will look like:
list.OrderBy(item => item.BIN).ThenBy(item => item.Code);
instead of the much uglier option you need to do if you have arrays/lists:
list.OrderBy(item => item[0]).ThenBy(item => item[1]);
Note how the first example reads exactly like your requirements. "Order the list by BIN and then by Code." It's perfectly clear to someone looking at the code for the first time exactly what it's doing.

List containing Dictionary Containing List

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]

Categories

Resources