for reporting purposes i wanna split a list of purchase orders into multiple lists. One list for each purchase address. I know it's possible to group the list by purchase address, but my question is how to split the list by this purchase address into multiple lists and use these multiple list to create individual reporting files.
code:
(from o in orders
group o by new {field1, field2, field3, field4} into og
orderby og.Key.field1
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count
}).ToList()
question: how to split above list into multiple lists for each purchaseAddress?
There's a built-in function that I think does what you want. If I assume that your code is assigned to a variable called query then you can write this:
ILookup<string, ViewClass> queryLists = query.ToLookup(x => x.purchaseAddress);
This essentially creates a list of lists that you access like a dictionary, except that each value is a list of zero or more values. Something like:
IEnumerable<ViewClass> someList = queryLists["Some Address"];
Just turn each group into a List.
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count,
List = og.ToList()
}).ToList();
Oh, your grouping is one way for entities and another way for pages... just regroup.
List<ViewClass> classes = (
from o in orders
group o by new {field1, field2, field3, field4} into og
orderby og.Key.field1
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count
}).ToList();
List<List<ViewClass>> regrouped = (
from c in classes
group c by c.purchaseAddress into g
select g.ToList()
).ToList();
Another simple built-in function that you can use is the GroupBy function. It does a similar job as the ToLookup but it means that your new list is IQuerable, not like a dictionary and a few other things (see this article for a good breakdown)
var newList = orders.GroupBy(x => x.field1);
This will return a list of lists grouped by the field(s) you specify.
Related
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;
I have list e.g:
list1=
{{id=1,address=a},
{id=1,address=b},
{id=2,address=c},
{id=2,address=d}}
how can i change this list into something like
list2=
{{id=1,address={a,b}},
{id=2,address={c,d}}}
that is putting same id's list into one with inner list containing other elements
group is your friend here. Assuming the output type's address property is a List<T> something like:
var res = (from x in input
group x by x.id into grouped
select new Output {
id = grouped.Key,
address = grouped.ToList()
}).ToList();
I have two lists:
Products
A list of Product and Warehouse combination containing
prices/quantities etc.
Two seperate results of sql queries.
The second list has a 'ProductId'.
What I'm currently doing is:
foreach(var product in Products)
var productWarehouses = Warehouses.Where(x=> x.ProductId == productId).ToList();
product.Warehouses = productWarehouses;
Thing is, this takes very, very long.
Note: I've tried splitting Products into chunks of lists and using Parallel.Foreach() and Tasks to take the time down - but still takes very long.
Use a Join rather than doing a linear search through the entirety of one collection for each item in the other collection:
var query = from product in Products
join warehouse in Warehouses
on product.productId equals warehouse.ProductId
into warehouses
select new
{
product,
warehouses,
};
Instead of doing this in c#, I would prefer to do it in SQL stored procedure. Get all details from one sql and then iterate though result to create Product list.
Create a Dictionary<int, Product> from your Products where Product.ProductID is used as key:
var pd = Products.ToDictionary(p => p.ProductID, p => p);
then you can iterate over Warehouses and lookup appropriate products fast:
foreach (var wh in Warehouses)
{
pd[wh.ProductId].Warehouses.Add(wh); //supposed Product.Warehouses lists have already been created, if not, add checks and create them as needed.
}
I have struggled with it for a long time. I have two collections: MyRepository.All and MyCollection, both holds the collection of objects which has ID property. I need to get result of list of objects from MyRepository.All what contains only objects which id's are equal to MyCollection's objects'ids.
ICollection MyCollection // as parameter to method
var result = MyRepository.All.Where(r=>r.id==MyCollection.???.id).ToList();
i need to replace ??? with some linq to get this done.
ive tried different where and select caluses, excist and intersect and so on..
from a in MyRepository.All
join m in MyCollection on a.Id equals m.Id
select a
Cache the ids of MyCollection into a HashSet.
Than you can retrieve your result with a Where clause like this :
var myIdSets = new HashSet(MyCollection.Select(c => c.Id));
var result = MyRepository.All.Where(r=> myIdSets.Contains(r.id)).ToList();
var result = (from r in MyRepository.All
join r2 in MyCollection on r.id equals r2.id
select r).ToList();
MyRepository.All.Where(r=>MyCollection.Select(a=>a.id).Contains(r.id))
Linq has an .Intersect that should get you want you need.
Something like this:
var result = MyRepository.Intersect(MyCollection).ToList();
More info:
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect.aspx
This is a complete Newbie question and I understand but how do I transfer these two distinct Enumerable collections to a single ObservableCollections?
var distinctLine1 = (from z in list
orderby z.ItemLine1
select z.ItemLine1).Distinct();
var distinctLine2 = (from z in list
orderby z.ItemLine2
select z.ItemLine2).Distinct();
foreach (var item in distinctLine1)
{
}
Sorry did change ObservableCollectionsList to ObservableCollections
ItemLine1 and ItemLine2 are both strings
I suppose you could probabl also call Distinct on union to exclude possible duplicates.
var union = distinctLine1.Union(distinctLine2).Distinct();
Or just
var union = distinctLine1.Union(distinctLine2);
And then simply create the target collection with ObservableCollection Constructor (IEnumerable):
var result = new ObservableCollection<string>(union);