Click here to Skip to main content
15,897,371 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi
I have some problems with a lambda expression. Of course the some could be done with foreach loops but I would prefer reasonably simple lambda expression.

I have a following method

C#
private IEnumerable<IContainer> GetContainers()
{
...
}


as you can see the method should return a collection of IContainer instances where an IContainer is the following interface
public interface IContainer
{
IEnumerable<MyItem> Items{get;}
int Id{get;}
}

Inside GetContainers() method I retrive the collection of IContainer instances, where some of the containers can have the same Id. I need a lambda expression which would transform that collection into a collection where each container has a different Id. If the source collection had containers with same Ids, the destination collection should have only one container with that Id, but it's Items property should contain all items found in containers with that Id. I hope my question is described clearly enough to be understood. I could post the existing code which uses the foreach loops, but I think that the text above is easier to understand. Any ideas will be appreciated.

Uroš
Posted

You haven't given much to go on so far in respect to how your getting the data out of the database etc.

I have made a simple example that should help you get distinct values from the collection using lambda.

C#
List<test> d = new List<test>();

for (int i = 0; i <= 5; i++)
{
  d.Add(new TEst { ID=i, Name="Simon" });
}

d.Add(new TEst { ID = 1, Name = "Simon" });

var x = (from s in d select s).Distinct();




Definition for the TEst class
C#
public class TEst
{
 public int ID { get; set; }
 public string Name { get; set; }
}
 
Share this answer
 
v2
Comments
koleraba 27-Nov-12 7:37am    
Hi. Thank you for your reply. The Distinct() method does not do me any good, because if you look at the IContainer interface you will see that it contains a property Items of type IEnumerable<t>. So for example, if my input colletion of containers contains two containers with an Id = 1, and each has 3 Items(Items.Count() == 3) than my output collection has to contain one container with an Id = 1 which has 6 items. The data on which the lambda should operate("input collection" in the text above), is retrived from the .xml file. I don't see how the information on how I retrive data from the .xml file would be benefitial to the explanation?
Simon_Whale 27-Nov-12 7:49am    
because having an idea of what data you are using allows us to formulate a usable solution for you AS lambda might not be the best way to go.
GetContainers() will need to construct a new collection of class instances that implement the IContainer interface. Then you can use the .GroupBy() extension method.

This does what I think you are looking for:
C#
// example proxy for IContainer-implementing class
public class TestItem
{
  public List<int> Items;
  public int Id;
}

// example:
List<TestItem> test = new List<TestItem>();
var item1 = new TestItem { Id = 1, Items=new List<int>()};
item1.Items.Add(10);
item1.Items.Add(11);
item1.Items.Add(12);
test.Add(item1);
var item2 = new TestItem { Id = 2, Items=new List<int>()};
item2.Items.Add(20);
item2.Items.Add(21);
item2.Items.Add(22);
test.Add(item2);
var item3 = new TestItem { Id = 1, Items=new List<int>()};
item3.Items.Add(30);
item3.Items.Add(31);
item3.Items.Add(32);
test.Add(item3);

var selected = test.GroupBy(m => m.Id)
                   .Select(g => g.Aggregate(new TestItem() { Id = g.Key, 
                                                             Items = new List<int>() }, 
                                            (agg, item) => { agg.Items.AddRange(item.Items); 
                                                             return agg; }));
Console.WriteLine(selected.Count());
 
Share this answer
 
v2
Comments
koleraba 27-Nov-12 20:59pm    
Thank you Matt. That is exactly what I needed. The part that construsts a new collection of instances implementing the IContainer I already have. I just needed the lambda that you provided in your post. Thanks again.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900