I have the following classes:
public class MyItem
{
public string Email;
public int Value1;
public datetime Value2;
//etc
}
public class MyItems : List<MyItem> {}
I populate a MyItems object with a list of random items. Now I need to break this list into smaller lists, whereby each list contains only the items that have the same 'Email' property.
Can this be achieved using Linq?
If you have a List<MyItem> you can simply use GroupBy:
myItems.GroupBy(x => x.Email).Select(g => g.ToList());
This will return a IEnumerable<List<MyItem>>
Or you can use ToDictionary and you can access your groups by Email:
myItems.GroupBy(x => x.Email).ToDictionary(x => x.Key, x => x.ToList());
Try this
MyItems myItems = new MyItems();
//Populate here
myItems.GroupBy(x => x.Email).Select(group => group.ToList());
Here you get a collection of lists that you can use
Related
I have a field that looks like:
public Dictionary<ClassA, List<ClassB>> MyDict;
Assume that:
public class ClassA
{
public string Name;
public int Id;
}
public class ClassB
{
public string Tag;
public string Text;
}
I'm trying to define a query that is of IEnumerable<KeyValuePair<ClassA,IEnumerable<ClassB>> type where I define a condition on the value of ClassB.Tag. I tried things like:
IEnumerable<KeyValuePair<ClassA,IEnumerable<ClassB>> q =
MyDict.Where(pair => pair.Value.Any(b => b.Tag == "a tag"));
But obviously the above is not what I need because it returns the whole List<ClassB> if any item matches that condition, while what I want is to return an IEnumrable or a List of items that match the condition.
dotNetFiddle demo
You need to construct the IEnumerable from a call to ToDictionary, where you use a projection to only take the matching BClass from the list and only take the result from that set where values in the BClass list were actually matched.
IEnumerable<KeyValuePair<ClassA,List<ClassB>>> q = MyDict.ToDictionary(
k => k.Key,
k => k.Value.Where(b => b.Tag == "10").ToList()
).Where(kv => kv.Value.Any());
public class Ex
{
public string example1{get;set;}
public string example2{get;set;}
public Test test{get;set;}
}
public class Test
{
public string example3 {get;set;}
public long[] arrayLong{get;set;}
}
I have List listEx for example 10 elements. How get arraylong?
long[] result = listEx.Select( x=> x.Test.Select(y =>y.arrayLong)).ToArray();
I need only long[] how parse it?
Use SelectMany function, which will "flatten" collection of collections to one collection.
var result = listEx.SelectMany(ex => ex.Test.Select(test => test.arrayLong)).ToArray();
From MSDN: Enumerable.SelectMany Method
You should use SelectMany
var outresult = listEx.SelectMany(t => t.Test.Select(s => s.arrayLong)).ToArray();
I have two models:
class Foo
{
public List<Bar> Bars { get; set; }
}
class Bar
{
public int Value { get; set; }
}
Having an instance of List<Foo>, how can I get all Value using a LINQ query?
Thank you all
SelectMany is normally the way to flatten hierarchies, so:
var values = myList.SelectMany(foo => foo.Bar)
.Select(bar => bar.Value);
The SelectMany will give you an IEnumerable<Bar>, and then the Select projects that sequence of Bar objects to the Value property of each, returning an IEnumerable<int>.
As a query expression, this would be:
var values = from foo in myList
from bar in foo.Bar
select bar.Value;
I suggest you to change List<Bar> property name to Bars.
And firstly use SelectMany(). It projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence. And then use Select() to project each element of a new sequence as you wish.
var result = myList.SelectMany(x => x.Bars).Select(x => x.Value).ToList();
Use SelectMany instead of Select
var result = LIST1.SelectMany(x => x.LIST2.Select(y => y.Value)).Tolist();
I have two classes
public class X
{
string title;
}
public class Y
{
string name;
IList<X> testList;
}
I have a list like below
IList<Y> myList = new List<Y>();
I want to sort myList based on the name and title
How can I do it?
Try something like this,
var sorted = lstY.OrderBy(c => c.name).ToList().Select(d => { d.testList.OrderBy(f => f.title); return d; });
myList.OrderBy(x => x.name).ThenBy(y => y.testList.Min(z=>z.title));
This is one option but not the only option. Add a public or internal getter to class Y:
public IEnumerable<X> TestList{get{return testList.OrderBy(x=>x.title);}}
When retrieving your list of Y, clearly you can sort it by name:
myList.OrderBy(y=>y.name);
And for whatever processing you are doing, such as diplaying the list of Y, you would display Y.name and foreach X in TestList the X.title will be sorted.
or even without that second getter:
myList.OrderBy(y=>y.name).Select(y=>new{y.name, testList=y.testList.OrderBy(t=>t.title)}).Dump();
I have two different lists where one is a bunch of ID's as in a List<int> idsList, the other however is a list of objects like List<MyObject> myObjectList where the object looks like this:
class MyObject{
private List<int> ids;
public MyObject(List<int> ids){
this.ids = ids;
}
public List<int> Ids{
get{
return ids;
}
}
}
As you can see each object can contain one or multiple IDs (never zero or null ids). So what I need at the end is to know what objects in myObjectList have any id(s) from my idsList.
So far if I do:
var ids = from g in onScreen where g.Ids.Contains(myIntVariable) select g;
it would give me a list of the object(s) that contain myIntVariable. What I do not know how to do is to match the content of the idsList with the list in MyObject.
Thanks!
One way to go:
var listOfMyObjectsContainingAnIdFromIdsList = myObjectList.Where(myObject => myObject.Ids.Any(id => idsList.Contains(id)));
Assuming g is your object list and idsList is your int list:
foreach (var myObject in g.Where( obj => obj.Ids.Any( itemId => idsList.Contains(itemId) ) )) {
//Use your myObject here
}
Hope it works,