I have a list of objects each with its own id property. I need to create an icollection of ids from the stored objects. Is there an elegant way other than looping through the list of objects, grabbing the id value and dumping it into the collection?
LINQ is your friend :)
List<int> ids = entities.Select(x => x.Id).ToList();
or into an array if you must (as per question title):
int[] ids = entities.Select(x => x.Id).ToArray();
Of course that does just iterate over the collections, but it's code you don't have to write yourself...
Basically, whenever you find yourself wanting to do "something like this" - transforming, aggregating, filtering, flattening etc a collection - you should look at whether LINQ can help you.
how about using Linq (which will do the iteration for you) using a Select() projection with the properties you want (in your case just the Id):
var idCollection = someList.Select(x=> x.Id).ToList();
Linq to the rescue:
var names=Controls.Select(w=>w.Name).ToArray(); // where this is a form
Related
Is there a way to retrieve multiple single items from a dbset query. I'm trying to build a get multiplenumbereditems controller directive.
I take a string an convert it into an array of id's. I then sort the ids ascending.
I just don't know of a propper way to build my list or aƱ optimal dbset seek method that will sequentially take my id's and only return list built out of these items. Or is returning multiple single items my only option. My table is small enough to just grab them all but I want to build something now should the database grow.
The table has an auto generated I'd list and will stay sequential or am I making an assumption about speed here.
Any guidance. Thank you.
It sounds like you need to use the Contains method. For example, lets assume you have a list of ids like this:
var ids = new List<int> { 1, 2, 3, 4 };
You cn use that list directly like this:
var elements = context.Items.Where(i => ids.Contains(i.Id));
Hi guys i'm relatively new to LINQ so not the greatest of knowledge but i'm pretty sure this can be done using it.
I have two lists, a list of propertyAppliances and a list of engineerSkillsets.
The propertyAppliance object has an appliance sub-object with an applianceTypeId
The engineerSkillset object simply has this applianceTypeId.
I need to check if there is an appliance in that list that has an applianceTypeId that does not exist within the list of engineer skillsets.
Much appreciated!
If you only want to know whether there are any, I'd use:
if (propertyAppliances.Select(pa => pa.Appliance.TypeId)
.Except(engineers.Select(eng => eng.ApplianceTypeId))
.Any())
This effectively creates a set of appliance types from propertyAppliances, removes any appliance types from the set from the engineers, and sees whether there's anything in the result. I'd expect this to be more efficient than the answers which check every engineer against every appliance.
Try this one:
if(listA.Any(x=>list.B.Contains(y=>y.applianceTypeId==x.applianceTypeId))
{
}
where listA is the list of propertyAlliances and listB is the list of engineerSkillsets.
Try this:
var propertyAppliancesBasedOnApplianceTypeId = (from appliance in propertyAppliance
from skillset in engineerSkillsets
where !appliance.applianceTypeId.Contains(skillset.applianceTypeId)
select appliance).Any();
OR
var propertyAppliancesBasedOnApplianceTypeId = propertyAppliance
.Any(x=>!engineerSkillsets.Contains(x.applianceTypeId));
Both the methods will return true if record exists else it will return false
I have a very long list of Ids (integers) that represents all the items that are currently in my database:
var idList = GetAllIds();
I also have another huge generic list with items to add to the database:
List<T> itemsToAdd;
Now, I would like to remove all items from the generic list whose Id is already in the idList.
Currently idList is a simple array and I subtract the lists like this:
itemsToAdd.RemoveAll(e => idList.Contains(e.Id));
I am pretty sure that it could be a lot faster, so what datatypes should I use for both collections and what is the most efficient practice to subtract them?
Thank you!
LINQ could help:
itemsToAdd.Except(idList)
Your code is slow because List<T>.Contains is O(n). So your total cost is O(itemsToAdd.Count*idList.Count).
You can make idList into a HashSet<T> which has O(1) .Contains. Or just use the Linq .Except extension method which does it for you.
Note that .Except will also remove all duplicates from the left side. i.e. new int[]{1,1,2}.Except(new int[]{2}) will result in just {1} and the second 1 was removed. But I assume it's no problem in your case because IDs are typically unique.
Transform temporarily idList to an HashSet<T> and use the same method i.e.:
items.RemoveAll(e => idListHash.Contains(e.Id));
it should be much faster
Assuming the following premises are true:
idList and itemsToAdd may not contain duplicate values
you are using the .NET Framework 4.0
you could use a HashSet<T> this way:
var itemsToAddSet = new HashSet(itemsToAdd);
itemsToAddSet.ExceptWith(idList);
According to the documentation the ISet<T>.ExceptWith method is pretty efficient:
This method is an O(n) operation,
where n is the number of elements in
the other parameter.
In your case n is the number of items in idList.
You should use two HashSet<int>s.
Note that they're unique and unordered.
i have a collection
IEnumerable<Project>
and i want to do a filter based on project's Id property to included any id that is in a list:
List<int> Ids
what is the best way to do a where clause to check if a property is contained in a list.
var filteredProjectCollection = projectCollection.Where(p => Ids.Contains(p.id));
You may be able to get a more efficient implementation using the Except method:
var specialProjects = Ids.Select(id => new Project(id));
var filtered = projects.Except(specialProjects, comparer);
The tricky thing is that Except works with two collections of the same type - so you want to have two collections of projects. You can get that by creating new "dummy" projects and using comparer that compares projects just based on the ID.
Alternatively, you could use Except just on collections of IDs, but then you may need to lookup projects by the ID, which makes this approach less appealing.
var nonExcludedProjects = from p in allprojects where Ids.Contains(p => p.Id) select p;
If you're going to use one of the .Where(p=> list.Contains(p)) answers, you should consier first making a HashSet out of the list so that it doesn't have to do an O(n) search each time. This cuts running time from O(mn) to O(m+n).
I'm not sure that I understand your question but I'll have a shot.
If you have: IEnumerable enumerable,
and you want to filter it such that it only contians items that are also present in the list: List list,
then: IEnumerable final = enumerable.Where(e => list.Contains(e));
I'm storing a collection of objects of custom class type. I've given the type below.
public class AnonymousClient
{
private string ipAddress, city, country, category;
private Guid id;
}
I may have to get the objects filtered based on city, country, category etc. I'm able to think of two ways -
Storing it in a dictionary
Dictionary<Guid, AnonymousClient>
and using Linq to filter the
objects.
Storing it in a DataTable with
multiple columns for the members
and using DataTable.Select() to
filter the records.
I guess both of them loop internally. Which one is faster and elegant? Any insights?
Using a DataTable would add quite a bit of overhead. It's easier to run a query once you set it up, because the code for it is already created, but it won't run as fast.
If you want to look up items using the id you can use a Dictionary<Guid, AnonymousClient>, if you only want to filter the data on the other fields you can just use a List<AnonymousClient>.
The most efficient would be to simply loop the collection yourself and pick out the items. LINQ is almost as efficient, but it adds a slight bit of overhead. On the other hand, the LINQ code gets very simple.
Example using the LINQ extension method Where:
var companies = clients.Where(c => c.category == "Company");
I would go with the first approach. But do you really need to store them in Dictionary? You already have them in a collection right? you could use LINQ to filter on the collection itself.
var cityFiltered = from p in AnonymousClientList where p.city == 'London' select p;
etc.. and build your filtered collection.
======UPDATE======
Here is the updated query for filtering using city:
var filtered = (from c in clients where c.Value.city=="London" select c).ToDictionary(x => x.Key, x => x.Value);
If you see, the first part basically returns you a boolean value for your condition and not the dictionary object that you need. By using the ToDictionary method, you convert back to a Dictionary. So, now after execution of the LINQ, you will have all AnonymousClient with city set to London.