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();
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());
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
I have a Dictionary that contains thread Information Dictionary<String,Thread>
"2FF"
"2IE"
"7CH"
etc
what i know is integers 2,7 etc what i want to know that in Dictionary how many strings contain the given integer if it is there then get that string
Eg
String GetString(int integer)
{
//if Dictionary contains given intgr return whole string in which that integer is present
}
}
With LINQ syntax:
var matchingThreads = from pair in dictionary
where pair.Key.StartsWith(number.ToString())
select pair.Value;
With traditional syntax:
var matchingThreads = dictionary
.Where(pair => pair.Key.StartsWith(number.ToString()))
.Select(pair => pair.Value);
If you only need to count them and you don't care about the Thread objects, you can use:
int count = dictionary.Keys.Count(key => key.StartsWith(number.ToString()))
Note that you need a using System.Linq directive.
Maybe a List<CustomClass> would be a better choice here where CustomClass would look like:
public sealed class CustomClass
{
public Thread Thread { get; set; }
public string String { get; set; }
}
(Better property names are alway good, of course :-) )
A dictionary is not sutitable if you do not know the exact keys or only parts of them.
You could then use LINQ to find out what you want, e.g.:
int count = list.Where(c => c.String.StartsWith(integer.ToString())).Count();
//or
IEnumerable<string> strings = list.Where(c => c.String.StartsWith(integer.ToString())).Select(c => c.String);
public IEnumerable<string> GetMatchingKeys(int value)
{
var valueText = value.ToString();
return _dictionary.Keys.Where(key => key.Contains(valueText));
}
How to check if an IEnumerable has two or more items with the same property value ?
For example a class
public class Item
{
public int Prop1 {get;set;}
public string Prop2 {get;set;}
}
and then a collection of type IEnumerable<Item>
I need to return false if there are items with duplicate values in Prop1.
You want to check only for Prop1 right ?
What about:
IEnumerable<Item> items = ...
var noDistinct = items.GroupBy(x => x.Prop1).All(x => x.Count() == 1);
// it returns true if all items have different Prop1, false otherwise
I think this method will work.
public static bool ContainsDuplicates<T1>(this IEnumerable<T1> source, Func<T1, T2> selector)
{
var d = new HashSet<T2>();
foreach(var t in source)
{
if(!d.Add(selector(t)))
{
return true;
}
}
return false;
}
A short, one-enumeration only solution would be:
public static bool ContainsDuplicates<T>(this IEnumerable<T> list)
=> !list.All(new HashSet<T>().Add);
which could be read as: A list has no duplicates when All items can be Add-ed to a set.
This is conceptually similar to Jake Pearsons solution; however, it leaves out the independant concept of projection; the OP's question would then be solved as:
items.Select(o => o.Prop1).ContainsDuplicates()
bool x = list.Distinct().SequenceEqual(list);
x is true if list has duplicates.
Have you tried Enumerable.Distinct(IEnumerable, IEqualityComparer)?
You can select the distinct values from the IEnumerable and then check the count against that of the full collection.
Example:
var distinctItemCount = myEnumerable.Select(m => m.Prop1).Distinct().Count();
if(distinctItemCount < myEnumerable.Count())
{
return false;
}
This could potentially be made for performant, but it's the only correct answer so far.
// Create an enumeration of the distinct values of Prop1
var propertyCollection = objectCollection.Select(o => o.Prop1).Distinct();
// If the property collection has the same number of entries as the object
// collection, then all properties are distinct. Otherwise there are some
// duplicates.
return propertyCollection.Count() == objectCollection.Count();
public static class EnumerableEx
{
public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> source)
{
return source.GroupBy(t => t).Where(x => x.Count() > 1).Select(x => x.Key);
}
}
Personally, I like the neatness of extension methods.
If your objects don't require a selector for determining equality, then this works nicely.
We can remove duplicate entries by using .Distinct() in ArrayList.
Example:
I have a createdby column in testtable with 5 duplicate entries. I have to get only one row
ID Createdby
=== ========
1 Reddy
2 Reddy
3 Reddy
4 Reddy
Considering the above table, I need to select only one "Reddy"
DataTable table=new DataTable("MyTable");//Actually I am getting this table data from database
DataColumn col=new DataColumn("Createdby");
var childrows = table.AsEnumerable().Select( row => row.Field<object>(col)).Distinct().ToArray();
i have a objectA
public class objectA
{
public int Id;
public string Name;
}
i have a list of objectA
List<objectA> list;
i want to find in the list any objectA with Id = 10;
is there linq syntax for this or do i simply have to write a loop here.
list.Where(o => o.Id == 10);
Remember: you can chain those method calls, or you can use the IEnumerable returned here for things like databinding.
To return all objects with an Id of ten, you'll need:
list.Where(o => o.Id = 10)