C# List values compare and add - c#

var bndlSummary = GetBundleSummary(GroupIds);
var cntrSummary = GetContainerSummary(GroupIds);
var finalSummary = GetFinalSummary(GroupIds);
Above var are fetching some data from Database. They all have one Common Field Name "City".
City value can be repeated many time like City = Chicago can be 3 times or more). now I want this Field City value into allCityNames. I don't want City Info to be repeated from any var.
var allCityNames = new cityAnalysisSummary();
Please help me how how should i do it. Thank you very much for your help.

bndlSummary.Select(b => b.City)
.Concat(cntrSummary.Select(c => c.City))
.Concat(finalSummary.Select(f => f.City))
.Distinct();
Use Select to get all the cities from each collection, Concat to put them all together, and Distinct to remove any duplicates.
You can also use Union which will remove duplicates while concatenating:
bndlSummary.Select(b => b.City)
.Union(cntrSummary.Select(c => c.City))
.Union(finalSummary.Select(f => f.City));

Related

sorting by using linq comparing two lists?

I have 2 list of items;
IEnumerable<Investigator> investigators = RepositoryContext.InvestigatorRep.GetInvestigators(site.Site.Id, out totalCount);
var NewInvestigators = base.ActivePage.Investigators;
I have 30 items in investigators and 20 items in NewInvesigators, both have property Id, InvId I need to match that.
var all = investigators.Where(b => crInvestigators.Any(a => a.InvestigatorId == b.Id));
I tried this but not worked
I want to create a new list based on matching Id of those two lists. If Id matches get the particular investigator(basically a sort on investigators based on Id existing in NewInvesigators).
I can do it by using for each, but I want to know whether it is possible with linq?
in newinvestigator I have object which is having two property, investigatorId and Name.
In Investigator I have property Id , City , country.
no Name or investigatorId in the investigator list.
You could try something like this:
var result = investigators.Where(inv=>NewInvestigators.Any(ninv=>ninv.id == inv.investigatorId))
.OrderBy(inv=>inv.id);
Another way to get the same result is using a join.
var result = from inv in investigators
join ninv in NewInvestigators
on inv.id equals ninv.investigatorId
order by inv.id
select inv;

C# Linq multiple GroupBy and Select

I have two objects that are linked, States and Cities, so each State has his Cities and each Citie is linked to an State. I also have some Units that have stateID and citieID but they are not linked since i have them only in Json.
What i need is to get only the States and Cities that have Units. I managed to get the first two but was wondering if there was any faster way to do it since i will have to make an update on those datas everyday:
//unitsData have a List of Units objects, this only have stateID, citieID and the unit data
var unitsData = objUnidade.BuscaUnidades();
//unitsState have all units grouped by State, here i also only have stateID and citieID, same data as above
var unitsState = unitsData.GroupBy(x => x.codigoEstado);
//Here is where i make my search inside the unidadesEstados and select only the Estados that i need
var activeStates = unitsState.Select(est => db.States.FirstOrDefault(x => x.ID == est.Key)).Where(state => state != null).ToList();
To do the Cities search i'm doing the same but using an extra foreach, is there a way to make this better ?
You are querying the database multiple times. It's better to use a SELECT ... IN query, which in LINQ looks like:
var units = objUnidad.BuscaUnidades();
var stateIds = units.Select(u => u.codigoEstado).ToList();
var activeStates = db.States.Where(s => stateIds.Contains(s.Id)).ToList();
EDIT: you asked about cities as well. It's more of the same:
var cityIds = units.Select(u => u.codigoCuidad).ToList()
var activeCities = db.Cities.Where(c => cityIds.Contains(c.Id)).ToList();
This solution gives you every city whose ID is referred to by a unit. #StriplingWarrior 's solution will give you every city in (the states that have a unit).
If db.States queries the database, then for each group in unitsState the query will get executed. If the number of states isn't extremely large, you can store them in a list.
var dbStates = db.States.ToList();
var activeStates = unitsState.Select(est => dbStates.FirstOrDefault(x => x.ID == est.Key)).Where(state => state != null).ToList();

LINQ contains between 2 lists

I have a string List and a supplier List<supplier>.
string list contains some searched items and supplier list contains a list of supplier object.
Now I need to find all the supplier names that matches with any of the items in the string List<string>.
this is one of my failed attempts..
var query = some join with the supplier table.
query = query.where(k=>stringlist.contains(k.companyname)).select (...).tolist();
any idea how to do that??
EDIT:
May be my question is not clear enough...I need to find a list of suppliers(not only names,the whole object) where suppliers names matches with the any items in the string list.
If I do
query = query.where(k=>k.companyname.contains("any_string")).select (...).tolist();
it works. but this is not my requirement.
My requirement is a list of string not a single string.
Following query will return distinct suppliers names which exist in list of names:
suppliers.Where(s => stringlist.Contains(s.CompanyName))
.Select(s => s.CompanyName) // remove if you need whole supplier object
.Distinct();
Generated SQL query will look like:
SELECT DISTINCT [t0].[FCompanyName]
FROM [dbo].[Supplier] AS [t0]
WHERE [t0].[CompanyName] IN (#p0, #p1, #p2)
BTW consider to use better names, e.g. companyNames instead of stringlist
You could use Intersect for this (for just matching names):
var suppliersInBothLists = supplierNames
.Intersect(supplierObjects.Select(s => s.CompanyName));
After your EDIT, for suppliers (not just names):
var suppliers = supplierObjects.Where(s => supplierNames.Contains(s.CompanyName));
var matches = yourList.Where(x => stringList.Contains(x.CompanyName)).Select(x => x.CompanyName).ToList();
Either use a join as Tim suggested or you could just use a HashSet directly. This is much more efficient that using .Contains on a List as in some of the other answers.
var stringSet = new HashSet(stringList);
var result = query.Where(q => stringSet.Contains(q.Name));

Linq, filter out multiples

I have written a Search-function in my MVC-project, it matches a database.
The database have the struct like this:
Name - string (The name of the data)
SubName - string (the subname of the data)
SomeData - int (the actual data)
So if i have like 100 posts with a name and a specific subname with different values for the data. and then 100 posts more with the same name but a different subname.
Now when i search the database i use this linq-code;
var names = db.Graphs
.Where(r => r.Name.Contains(term))
.Take(5).Distinct()
.Select(r=> new {label = r.Name});
I thougth that that maby would get med 5 distinct answers, but it dosent...
I get five of the first 100 post, i would like to filter so that i take only uniqe name with subnames. So in the example above i would have revived 2 entrys.
Feel like i have tried everything and failed so any input would be appriciated.
var names = db.Graphs
.Where(r => r.Name.Contains(term))
.GroupBy(s=>s.Name).Take(5)
.Select(r => new { label = r.FirstOrDefault().Name });
You should apply Distinct() before Take().I hope this will help.

Getting records in between two records using Linq

I have a list of objects and need to get the list of records from this list. like I have of Countries and I need to get the list of countries which are in between country with name "Australia" and country "Indonasia", the list will not be sorted.
Am using c#.
I tried to use something like, get the index of first and second and then use that to get the list with a for loop, but would be handy if it can be done in single query.
If you do the following:
var elementsBetween = allElements
.SkipWhile(c => c.Name != "Australia")
.Skip(1) // otherwise we'd get Australia too
.TakeWhile(c => c.Name != "Indonasia");
you'll get the result you want without iterating through the list 3 times.
(This is assuming your countries are e.g. Country items with a Name string property.)
Note that this doesn't sort the countries at all - it's unclear from your question whether you want this or not but it's trivial to add an OrderBy before the SkipWhile.
this should do the job
var query = data.SkipWhile(x => x != "Australia").TakeWhile(x => x != "Indonesia")

Categories

Resources