Linq - How To Check Intersecting Objects Between Lists - c#

I have two list of objects. For e.g. say the objects are like below
class A
{
int ID;
int Value;
}
class B
{
int ID;
int Value;
}
I have two list of above objects like List<A> AList and List<B> BList. I want to find if any object in List<B> has matching Value from List<A>.
For now, what I do like is
foreach(var item in AList)
{
if(!BList.Any(x => x.Value == item.Value))
{
//Handle the error message
}
}
Is there any better way to do it by Linq?

You can do it this way. This will be true if there are any items in BList that have matching values in AList:
BList.Any(b => AList.Select(a => a.Value).Contains(b.Value))

Simply:
from a in AList
join b in BList on a.Value equals b.Value
select a

Try this:
BList.Any(b => AList.Any(a => a.Value == b.Value));

According to your current code, and if you just need to handle error when any item in AList doesn't have a matching item in BList, you can do as follows :
if (AList.Any(a => !BList.Any(b => b.Value == a.Value)))
{
//Handle error
}
Or if you need to take an action on every item in AList that doesn't have a matching item in BList :
foreach(var item in AList.Where(a => !BList.Any(b => b.Value == a.Value)))
{
//Handle error for current `item`
}
Anyways, the reason to prefer LINQ over conventional foreach loop is usually more for its readability (shorter, cleaner, easier to maintain, etc.) rather than performance. For reference : Is a LINQ statement faster than a 'foreach' loop?

This is what I've tried and it seems to work just fine:
class First
{
public int Id { get; set; }
public int Value { get; set; }
}
class Second
{
public int Id { get; set; }
public int Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var firstList = new List<First>
{
new First { Id = 1, Value = 2 },
new First { Id = 1, Value = 10 },
new First { Id = 1, Value = 0 }
};
var secondList = new List<Second>
{
new Second { Id = 1, Value = 2 },
new Second { Id = 1, Value = 2 },
new Second { Id = 1, Value = 4 }
};
bool hasCommonValues = firstList.Select(f => f)
.Any(u => secondList.Select(x => x.Value)
.Contains(u.Value));
Console.WriteLine(hasCommonValues);
}
}

Related

merge 2 lists into a new list that contains both data from list 1 and list 2 - where the unique key is "VariantId"

I have two lists of data (they are using the same class "SaleNumber").
Each list contains a list of sale numbers. The first list is taken from the danish "DK" database and the other from the swedish database.
Right now I am looping through the danish list For each item I loop through I find the item with the same variant id in the swedish list and then I join the data into a new list called saleNumbers.
The problem with this is that because I loop through the danish list then if the danish list doesn't have salenumbers for that variant id then it won't loop through this variant. If this happens then the swedish list item won't be added either - and therefore the salenumbers item won't be created - even though it should - it should have a 0 in salenumbers.totalsalesDK and the actual salenumber for the salenumbers.totalsalesSE.
How do I merge the two together into salenumbers without missing any variants?
I still want the structure retained - so that for instance I have the SaleNumbers.TotalSales showing sum of totalsales for both dk and se together. And the SaleNumbers.TotalSalesDK showing DK sales and SaleNumbers.TotalSalesSE showing SE sales for that item. The primary unique key is always the variantId. Here is my current code:
private List<SaleNumber> ConvertDataTableToSaleNumbers(DataTable dt)
{
List<SaleNumber> saleNumbers = new List<SaleNumber>();
foreach (DataRow dr in dt.Rows)
{
saleNumbers.Add(new SaleNumber() { ProductId = int.Parse(dr["productid"].ToString()), TotalSales = int.Parse(dr["totalsales"].ToString()), VariantId = int.Parse(dr["variantid"].ToString()) });
}
return saleNumbers;
}
DataTable dtDK = new Shoply.Data.DLOrderDetail().GetNumberOfSalesSinceOrderId(constDaysAgo,
Shoply.Data.DLBasis.GetTheConnectionToTheLanguage("dk"));
DataTable dtSE = new Shoply.Data.DLOrderDetail().GetNumberOfSalesSinceOrderId(constDaysAgo,
Shoply.Data.DLBasis.GetTheConnectionToTheLanguage("se"));
List<SaleNumber> saleNumbersDK = ConvertDataTableToSaleNumbers(dtDK);
List<SaleNumber> saleNumbersSE = ConvertDataTableToSaleNumbers(dtSE);
var saleNumbers = saleNumbersDK.SelectMany
(
foo => saleNumbersSE.Where(bar => foo.VariantId == bar.VariantId).DefaultIfEmpty(),
(foo, bar) => new SaleNumber
{
VariantId = foo.VariantId,
ProductId = foo.ProductId,
TotalSales = foo.TotalSales + (bar == null ? 0 : bar.TotalSales),
TotalSalesDK = foo.TotalSales,
TotalSalesSE = (bar == null ? 0 : bar.TotalSales)
}
);
EDIT:
Code updated to perform outerjoin
How about using Join in Linq.
Simple dotnetfiddle can be seen here : Dotnetfiddle link
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main(string[] args)
{
List<SaleNumber> saleNumbersDK = new List<SaleNumber> {
new SaleNumber() { VariantId="a",ProductId="A",TotalSales=10 },
new SaleNumber() { VariantId="b",ProductId="B",TotalSales=20 }
};
List<SaleNumber> saleNumbersSE = new List<SaleNumber> {
new SaleNumber() { VariantId="a",ProductId="A",TotalSales=10 },
new SaleNumber() { VariantId="c",ProductId="c",TotalSales=30 }
};
var innerjoin = saleNumbersDK.Join(saleNumbersSE, d => d.VariantId, s => s.VariantId, (d, s) =>
{
return new SaleNumber()
{
VariantId = d.VariantId,
ProductId = d.ProductId,
TotalSales = d.TotalSales+ (s == null ? 0 : s.TotalSales),
TotalSalesDK = d.TotalSales,
TotalSalesSE = (d == null ? 0 : d.TotalSales)
};
});
var pendingright= saleNumbersSE.Except(innerjoin, new CustomComparer());
var pendingleft = saleNumbersDK.Except(innerjoin, new CustomComparer());
var salesNumber= innerjoin.Concat(pendingright).Concat(pendingleft);
foreach (var sale in salesNumber)
{
Console.WriteLine(sale);
}
//Console.ReadLine();
}
}
public class SaleNumber
{
public string VariantId { get; set; }
public string ProductId { get; set; }
public int TotalSales { get; set; }
public int TotalSalesDK { get; set; }
public int TotalSalesSE { get; set; }
public override string ToString()
{
return VariantId+"-"+ProductId+"-"+TotalSales+"-"+TotalSalesDK+"-"+TotalSalesSE;
}
}
public class CustomComparer : IEqualityComparer<SaleNumber>
{
public bool Equals(SaleNumber x, SaleNumber y)
{
return x.VariantId == y.VariantId;
}
public int GetHashCode(SaleNumber obj)
{
return obj.VariantId.GetHashCode();
}
}
Assuming ProductId is the same for DK and SE you can use a group by function like this to get the result you want.
testDK.ForEach(s => s.TotalSalesDK = s.TotalSales);
testSE.ForEach(s => s.TotalSalesSE = s.TotalSales);
testDK.Concat(testSE)
.GroupBy(s => s.VariantId)
.Select(g => new SaleNumber() {
VariantId = g.First().VariantId,
ProductId=g.First().ProductId,
TotalSales = g.Sum(s=>s.TotalSalesDK) + g.Sum(s=>s.TotalSalesSE),
TotalSalesDK=g.Sum(s=>s.TotalSalesDK),
TotalSalesSE=g.Sum(s=>s.TotalSalesSE)
}).ToList()
You can use Concat and ToList methods:
var allProducts = productCollection1.Concat(productCollection2)
.Concat(productCollection3)
.ToList();

Code review of this portion of Linq Filters

I am a newbie of c #, I would like to know if I can remove the for each and do a single operation with Linq. I would like to return an IEnumerable with already filtered. is it possible to do this? Every suggestion is welcome, thank you very much
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Linq
{
class Oggetto
{
public int Id { get; set; }
public string MyProperty { get; set; }
public int Deleted { get; set; }
}
class Program
{
static void Main(string[] args)
{
IEnumerable<Oggetto> lista = new List<Oggetto> {
new Oggetto(){ Id = 1, MyProperty = "Propr1", Deleted = 0 },
new Oggetto(){ Id = 1, MyProperty = "Propr2", Deleted = 1 },
new Oggetto(){ Id = 2, MyProperty = "Prop3", Deleted = 0 },
new Oggetto(){ Id = 3, MyProperty = "Propr4", Deleted = 0 },
new Oggetto(){ Id = 3, MyProperty = "Prop5", Deleted = 1 }
};
foreach (var item in lista.Where(x => x.Deleted == 1).GroupBy(x => x.Id).Select(g => g.First()))
{
item.MyProperty = string.Join(",", lista.Where(t => t.Id == item.Id).Select(x => x.MyProperty).ToArray());
Console.WriteLine(item.Id);
Console.WriteLine(item.MyProperty);
}
Console.ReadLine();
}
}
}
You can use projection for this.
var orderedList = lista.GroupBy(x => x.Id)
.Where(x => x.Any(y => y.Deleted == 1))
.Select(x => new Oggetto
{
Id = x.Key, MyProperty = string.Join(",", x.Select(v => v.MyProperty))
});
foreach (var item in orderedList)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.MyProperty);
}
Anyway, as #Alex said you shoud replace Deleted field type to bool and as said by #Marco Salerno start programming in English you'll not regret.
First of all I would avoid the groupBy statement. This is a lot of unneded overhead. You can use distinct instead. This will give you all the IDs you need to know.
var ids = lista.Where(x => x.Deleted).Select(x => x.Id).Distinct();
You can then select all the elements that you need with:
var items = ids.Select(i => lista.Where(x => x.Id == i));
which results in a List of Lists. For the ease of use I would convert this to a Dictionary<K, V> (int this case it's Dictionary<long, List<string>> as a final step:
var dictionary = items.ToDictionary(l => l.First().Id, l => l.Select(o => o.MyProperty).ToList());
You now got a "nice and filtered" collection you can use any way you like (or just output it)
foreach (var item in dictionary)
{
Console.WriteLine($"Id: {item.Key}");
Console.WriteLine($"Properties: {string.Join(", ", item.Value)}");
}
I also changed your class a little bit to:
class Oggetto
{
public int Id { get; set; }
public string MyProperty { get; set; }
// bool instead of int - Deleted has only 2 states
public bool Deleted { get; set; }
}
First of all STOP programming in Italian, start doing it in English.
Anyway, this should be a better approach:
class Program
{
static void Main(string[] args)
{
List<Item> items = new List<Item> {
new Item{ Id = 1, MyProperty = "Propr1", Deleted = 0 },
new Item{ Id = 1, MyProperty = "Propr2", Deleted = 1 },
new Item{ Id = 2, MyProperty = "Prop3", Deleted = 0 },
new Item{ Id = 3, MyProperty = "Propr4", Deleted = 0 },
new Item{ Id = 3, MyProperty = "Prop5", Deleted = 1}
};
foreach (IGrouping<int,Item> group in items.GroupBy(x => x.Id).ToList())
{
List<Item> groupItems = group.ToList();
Item deletedItem = groupItems.Where(x => x.Deleted == 1).FirstOrDefault();
if(deletedItem != null)
{
deletedItem.MyProperty = string.Join(",", groupItems.Select(x => x.MyProperty).ToArray());
Console.WriteLine(deletedItem.Id);
Console.WriteLine(deletedItem.MyProperty);
}
}
}
}
class Item
{
public int Id { get; set; }
public string MyProperty { get; set; }
public int Deleted { get; set; }
}

Faster alternative to populate data in list from second list with other properties

I've searched for a solution on SO but I couldn't find it, so I've made this new question.
I have 2 list of two different classes.
First class:
public class Class1
{
public int C1Property1 {get;set;}
public int C1Property2 {get;set;}
public int C1Property3 {get;set;}
}
And second class:
public class Class2
{
public int C2Property1 {get;set;}
public int C2Property2 {get;set;}
public int C2Property3 {get;set;}
}
And I have two list of those classes:
List<Class1> Class1List = new List<Class1>();
List<Class2> Class2List = new List<Class2>();
Now comes the hard part for me: Two of those properties in both classes have the same value, but with a different name: i.e. C1Property1 = C2Property1 and C1Property2 = C2Property2. The list Class1List has the property C1Property1 which is empty, and I need to populate it using the property from Class2List. I do this by using the following code:
foreach(var element1 in Class1List)
{
foreach(var element2 in Class2List)
{
if(element2.C2Property2 == element1.C1Property2)
{
element1.C1Property1 = element2.C2Property1;
}
}
}
This solution works how I intent it, but is very ugly and I have 2 foreach-loops which can be slow (list can contain over 10 000 elements). In the example classes I wrote only 3 properties to show how it works, but originally it has ~20 properties each, and only 2 of them are the same. Can I do this faster and more efficient? Some LinQ perhaps? I can't show more code, sorry. I hope that you will understand what I'm asking.
I need to take only one property from Class2List and place it on Class1List only when one of parameters in list are same.
In my second attempt i use something like that :
foreach (var element1 in Class1List)
{
foreach (var element2 in Class2List.Where(element2 => element2.C2Property2 == element1.C1Property2 ))
{
element2.C2Property2 = element1.C1Property2;
break;
}
}
This should be faster but still look ugly
So here I have three options:
Using LINQ
Class1List.ForEach(element1 =>
{
Class2 element2 = Class2List.FirstOrDefault(e2 => e2.C2Property2 == element1.C1Property2);
if (element2 != null) element1.C1Property1 = element2.C2Property1;
});
This took my machine 4.58s for 20000 elements in each list. And though the code looks (to me) a little better, this is effectivly the same as your code.
Using a dictionary
Using a dictionary to access the Class2 elements via a hash is really effective:
Dictionary<int, Class2> dictionary = Class2List.GroupBy(e2 => e2.C2Property2, e2 => e2).Select(elements => elements.First()).ToDictionary(e2 => e2.C2Property2, e2 => e2);
Class1List.ForEach(element1 =>
{
if (dictionary.ContainsKey(element1.C1Property2))
element1.C1Property1 = dictionary[element1.C1Property2].C2Property1;
});
This took my machine 0.00878s for 20000 elements in each list.
Parallel
If your data gets really really big, you might consider to use Parallel.ForEach
Dictionary<int, Class2> dictionary =
Class2List.GroupBy(e2 => e2.C2Property2, e2 => e2).Select(elements => elements.First()).ToDictionary(e2 => e2.C2Property2, e2 => e2);
Parallel.ForEach(Class1List, element1 =>
{
if (dictionary.ContainsKey(element1.C1Property2))
element1.C1Property1 = dictionary[element1.C1Property2].C2Property1;
});
But with only 20000 elements in each list this took my machine even longer (0.0197s) than the non-parallel version.
It was a pretty interesting thing to figure out, but I think something like this might work:
Class1List.ForEach(c1 =>
c1.C1Property1 = Class2List.Where(c2 => c2.C2Property2 == c1.C1Property2)
.Select(r => r.C2Property1)
.FirstOrDefault());
Here is a test class:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO_Test
{
public class ObjectA
{
public int Property1 { get; set; }
public int? Property2 { get; set; }
public override string ToString()
{
return String.Format("({0}, {1})", Property1, Property2);
}
}
public class ObjectB
{
public int Property1 { get; set; }
public int? Property2 { get; set; }
public override string ToString()
{
return String.Format("({0}, {1})", Property1, Property2);
}
}
class Program
{
static void Main()
{
var listA = new List<ObjectA>
{
new ObjectA { Property1 = 5, Property2 = null },
new ObjectA { Property1 = 16, Property2 = null },
new ObjectA { Property1 = 9, Property2 = null },
new ObjectA { Property1 = 38, Property2 = null }
};
var listB = new List<ObjectB>
{
new ObjectB { Property1 = 5, Property2 = 1 },
new ObjectB { Property1 = 9, Property2 = 2 },
new ObjectB { Property1 = 16, Property2 = 3 }
};
Console.WriteLine("BEFORE");
Console.WriteLine("ListA: {0}", String.Join(", ", listA));
Console.WriteLine("ListB: {0}", String.Join(", ", listB));
listA.ForEach(a =>
a.Property2 = listB.Where(b => b.Property1 == a.Property1)
.Select(r => r.Property2)
.FirstOrDefault());
Console.WriteLine("AFTER");
Console.WriteLine("ListA: {0}", String.Join(", ", listA));
Console.WriteLine("ListB: {0}", String.Join(", ", listB));
Console.ReadLine();
}
}
}
Output:
BEFORE
ListA: (5, ), (16, ), (9, ), (38, )
ListB: (5, 1), (9, 2), (16, 3)
AFTER
ListA: (5, 1), (16, 3), (9, 2), (38, )
ListB: (5, 1), (9, 2), (16, 3)

.Net List ForEach Item

I have 2 objects:
public class ClassA
{
public int Id
public string name;
public ClassB myObjectB;
}
public class ClassB
{
public int Id
public string name
}
Having 2 Lists for <ClassA> <ClassB>
Some items from List1 match by Id with an item on List2... I want to set the objectB foreach item...
foreach(ClassA item in List1)
{
ClassB obj = (from b in List2 where b.Id == item.Id select b).SingleOrDefault()
if(obj != null)
{
item.myObjectB = obj;
////////break; <- ignore this
}
}
This solution works for me, but I'm just wondering if there is a better way to do this, instead of Foreach
Thanks everyone for your help!!!
I think that a foreach, in this case, is actually the appropriate approach, as you're mutating your list. You could potentially simplify your code a bit, however:
foreach(ClassA item in List1)
{
item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id);
}
This will set the item every time, though it will be set to null if there is no match. If you already have items in myObjectB and setting them to null is inappropriate, you could use:
foreach(ClassA item in List1)
{
item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id) ?? item.myObjectB;
}
Expanding on Reed's answer.. You can actually do this in a one-liner, because a list has a ForEach method.
List1.ForEach(item => item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id) ?? item.myObjectB);
List<ClassA> list1 = new List<ClassA>();
List<ClassB> list2 = new List<ClassB>();
list1.Add(new ClassA { Id = 2, name = "a2" });
list1.Add(new ClassA { Id = 3, name = "a3" });
list1.Add(new ClassA { Id = 4, name = "a4" });
list1.Add(new ClassA { Id = 5, name = "a5" });
list2.Add(new ClassB { Id = 1, name = "b1" });
list2.Add(new ClassB { Id = 2, name = "b2" });
list2.Add(new ClassB { Id = 4, name = "b4" });
list2.Add(new ClassB { Id = 5, name = "b5" });
// Goal is to set ClassA::myObjectB from List1 to
// matching instance (if any) of ClassB from List2
var query =
from a in list1
from b in list2
where a.Id == b.Id
select Tuple.Create(a, b);
foreach (var element in query)
element.Item1.myObjectB = element.Item2;
Update:
Or if you really don't want a for loop, I just realized you can use the fact that assignments return a value and at the same time make an entry in an obfuscated code contest :)
(from a in list1
from b in list2
where a.Id == b.Id
select a.myObjectB = b).ToList();
Update2:
I just thought of an alternate approach - depending on your scenario, a lazy mechanism might work for you?
public class ClassA
{
public int Id
public string name;
private ClassB myObjectB;
public ClassB MyObjectB {
get { return myObjectB ?? (myObjectB = list2.FirstOrDefault(x => this.Id == x.Id)); }
}
}
With classes defined as follows:
class ClassA {
public int Id { get; private set; }
public string name { get; private set; }
public ClassB myObjectB { get; set; }
public ClassA(int pId, string pName) {
Id = pId;
name = pName;
}
}
class ClassB {
public int Id { get; private set; }
public string name { get; private set; }
public ClassB(int pId, string pName) {
Id = pId;
name = pName;
}
}
You can do the following using the LINQ Join method:
var listA = new List<ClassA> {
new ClassA(1, "OneA"),
new ClassA(2, "TwoA"),
new ClassA(3, "ThreeA")
};
var listB = new List<ClassB> {
new ClassB(1, "OneB"),
new ClassB(2, "TwoB"),
new ClassB(4, "FourB")
};
listA
.Join(
listB,
itemA => itemA.Id,
itemB => itemB.Id,
(itemA, itemB) => new { ItemA = itemA, ItemB = itemB }
).ForEach(pair => pair.ItemA.myObjectB = pair.ItemB);
listA.ForEach(itemA => Console.WriteLine(
"{0} maps to {1}",
itemA == null
? "null"
: itemA.name,
(itemA == null || itemA.myObjectB == null)
? "null"
: itemA.myObjectB.name
));
Output is:
OneA maps to OneB
TwoA maps to TwoB
ThreeA maps to null

Using FindAll on a List<List<T>> type

Assuming
public class MyClass
{
public int ID {get; set; }
public string Name {get; set; }
}
and
List<MyClass> classList = //populate with MyClass instances of various IDs
I can do
List<MyClass> result = classList.FindAll(class => class.ID == 123);
and that will give me a list of just classes with ID = 123. Works great, looks elegant.
Now, if I had
List<List<MyClass>> listOfClassLists = //populate with Lists of MyClass instances
How do I get a filtered list where the lists themselves are filtered. I tried
List<List<MyClass>> result = listOfClassLists.FindAll
(list => list.FindAll(class => class.ID == 123).Count > 0);
it looks elegant, but doesn't work. It only includes Lists of classes where at least one class has an ID of 123, but it includes ALL MyClass instances in that list, not just the ones that match.
I ended up having to do
List<List<MyClass>> result = Results(listOfClassLists, 123);
private List<List<MyClass>> Results(List<List<MyClass>> myListOfLists, int id)
{
List<List<MyClass>> results = new List<List<MyClass>>();
foreach (List<MyClass> myClassList in myListOfLists)
{
List<MyClass> subList = myClassList.FindAll(myClass => myClass.ID == id);
if (subList.Count > 0)
results.Add(subList);
}
return results;
}
which gets the job done, but isn't that elegant. Just looking for better ways to do a FindAll on a List of Lists.
Ken
listOfClasses.SelectMany(x=>x).FindAll( /* yadda */)
Sorry about that, FindAll is a method of List<T>.
This
var result = from x in listOfClasses from y in x where SomeCondition(y) select y;
or
var result = listOfClasses.SelectMany(x=>x).Where(x=>SomeCondition(x));
To keep a list of lists, you could do something like this example:
MyClass a = new MyClass() { ID = 123, Name = "Apple" };
MyClass b = new MyClass() { ID = 456, Name = "Banana" };
MyClass c = new MyClass() { ID = 789, Name = "Cherry" };
MyClass d = new MyClass() { ID = 123, Name = "Alpha" };
MyClass e = new MyClass() { ID = 456, Name = "Bravo" };
List<List<MyClass>> lists = new List<List<MyClass>>()
{
new List<MyClass>() { a, b, c },
new List<MyClass>() { d, e },
new List<MyClass>() { b, c, e}
};
var query = lists
.Select(list => list.Where(item => item.ID == 123).ToList())
.Where(list => list.Count > 0).ToList();
query would be List<List<MyClass>> holding lists of MyClass objects that passed the test. At first glance, it looks out of order with the Where extension coming after the Select, but the transformation of the inner lists needs to occur first, and that's what's happening in the Select extension. Then it is filtered by the Where.
I would probably go with this
List<List<string>> stuff = new List<List<string>>();
List<List<string>> results = new List<List<string>>();
stuff.ForEach(list=> {var result = list.FindAll(i => i == "fun").ToList();
if (result.Count > 0) results.Add(result);
});
List<string> flatResult = new List<string>();
stuff.ForEach(List => flatResult.AddRange(List.FindAll(i => i == "fun")));
That way you can go with a jagged array or flatten it out.. But the Linq way works well too :-).
While producing a flat List<MyClass> will answer your need most of the time, the exact answer to your question is:
var result = (from list in ListOfClassLists
let listWithTheId=
(
(from myClass in list
where myClass.ID == id
select myClass)
.ToList()
)
where listWithTheId.Count > 0
select listWithTheId
).ToList();
This code snippet was taken from my Proof of Concept:
using System.Collections.Generic;
using System.Linq;
namespace ListOfListSelectionSpike
{
public class ListSpikeClass
{
public List<List<MyClass>> ListOfClassLists { get; set; }
private List<MyClass> list1, list2, list3;
public ListSpikeClass()
{
var myClassWithId123 = new MyClass("123");
var myClassWithIs345 = new MyClass("456");
list1 = new List<MyClass> { myClassWithId123, myClassWithIs345 };
list2 = new List<MyClass> { myClassWithId123, myClassWithIs345, myClassWithId123 };
list3 = new List<MyClass> { myClassWithIs345, myClassWithIs345 };
ListOfClassLists = new List<List<MyClass>> { list1, list2, list3 };
}
public List<List<MyClass>> GetListOfListsById(string id)
{
var result = (from list in ListOfClassLists
let listWithTheId =
((from myClass in list
where myClass.ID == id
select myClass)
.ToList())
where listWithTheId.Count > 0
select listWithTheId)
.ToList();
return result;
}
}
public class MyClass
{
public MyClass(string id)
{
ID = id;
Name = "My ID=" + id;
}
public string ID { get; set; }
public string Name { get; set; }
}
}

Categories

Resources