Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Suppose I have the following collection:
ONE
- Banana
- Mango
TWO
- Apple
- Mango
THREE
- Orange
- Pear
I want to get only the collection which do not have Mango in it, such as:
THREE
- Orange
- Pear
The following example returns wrong result:
List<Order> list = new List<Order> {
new Order { Id = 1, Name = "ONE", Items = new List<Items> { new Item { Id = 1, Nama = "Banana" }, new Items { Id = 2, Nama = "Mango" } }},
new Order { Id = 1, Name = "TWO", Items = new List<Items> { new Item { Id = 1, Nama = "Orange" }, new Items { Id = 2, Nama = "Mango" } }},
new Order { Id = 1, Name = "THREE", Items = new List<Items> { new Item { Id = 1, Nama = "Pear" }, new Items { Id = 2, Nama = "Chery" } }},
};
var result = list.Where(x => x.Item.Any(y => y.Nama != "Mango")).ToList();
Any will bail out as soon as a "Nama" different from 'Mango' is found which is not what you want.
x.Items.All(y => y.Nama != "Mango")
Should do it.
Related
Suppose I have the following collection:
ONE
- Banana
- Mango
TWO
- Apple
- Mango
THREE
- Orange
- Pear
I want to get only the collection which has Mango in it, such as:
ONE
- Banana
- Mango
TWO
- Apple
- Mango
The following example still returns a collection with 3 items:
List<Order> list = new List<Order> {
new Order { Id = 1, Name = "ONE", Items = new List<Items> { new Items { Id = 1, Nama = "Banana" }, new Items { Id = 2, Nama = "Mango" } }},
new Order { Id = 1, Name = "TWO", Items = new List<Items> { new Items { Id = 1, Nama = "Orange" }, new Items { Id = 2, Nama = "Mango" } }},
new Order { Id = 1, Name = "THREE", Items = new List<Items> { new Items { Id = 1, Nama = "Pear" }, new Items { Id = 2, Nama = "Chery" } }},
};
var result = list.Where(x => x.Items.Any(y => !y.Nama.Equals("Mango"))).ToList();
You are getting all collections where there is at least one item that is not Mango.
Try removing the "!".
var result = list.Where(x => x.Items.Any(y => y.Nama.Equals("Mango"))).ToList();
You're almost there! Try reading out the logic of your code to make sense of what it's is doing.
Your inner Where clause logic is saying 'Check the List and if Any of the entries does not Equal "Mango", then we keep that list'. With this logic, every entry in your list has a List with an entry that does not equal "Mango".
Reverse your logic so it says 'Check the List and if Any of the entries Equals "Mango", then we keep that list'.
var result = list.Where(x => x.Items.Any(y => y.Nama.Equals("Mango"))).ToList();
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to merge this two collection into one list but one of the collection is List<IGrouping<T>>. I am trying to merge the groupedSubscriptions (which is a List<IGrouping<int, Subscription>>) with the ListOfSubscriptionsSecond (which is a List<Subscription>) to create the FullListOfSubscriptions which is, finally, a List<Subscription>. See code sample below.
I'm getting a compile time error:
Severity Code Description Project File Line Suppression State Suppression State
Error CS1503 Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<int, ListObject.Program.Subscription>>' to 'System.Collections.Generic.IEnumerable<ListObject.Program.Subscription>'
Logical example of what I'm trying
List<Subscription> FullListOfSubscriptions = new List<Subscription>();
List<Subscription> ListOfSubscriptions = new List<Subscription>();
ListOfSubscriptions.Add(new Subscription() { SubscriptionId = 1, ParentProductId = 4, ChildProductId = 4, ParentProductName = "Product 1", ChildProductName = "Product 1", GroupId = 362 });
ListOfSubscriptions.Add(new Subscription() { SubscriptionId = 2, ParentProductId = 114, ChildProductId = 1, ParentProductName = "Product 2", ChildProductName = "Product 3", GroupId = 1 });
ListOfSubscriptions.Add(new Subscription() { SubscriptionId = 3, ParentProductId = 114, ChildProductId = 2, ParentProductName = "Product 2", ChildProductName = "Product 4", GroupId = 1 });
var groupedSubscriptions = ListOfSubscriptions.GroupBy(u => u.GroupId);
var flattenedSubscriptions = groupedSubscriptions.SelectMany(grp => grp.AsEnumerable()).ToList();
List<Subscription> ListOfSubscriptionsSecond = new List<Subscription>();
ListOfSubscriptionsSecond.Add(new Subscription() { SubscriptionId = 4, ParentProductId = 4, ChildProductId = 4, ParentProductName = "Product 1", ChildProductName = "Product 1", GroupId = 362 });
ListOfSubscriptionsSecond.Add(new Subscription() { SubscriptionId = 5, ParentProductId = 114, ChildProductId = 1, ParentProductName = "Product 2", ChildProductName = "Product 3", GroupId = 1 });
ListOfSubscriptionsSecond.Add(new Subscription() { SubscriptionId = 6, ParentProductId = 114, ChildProductId = 2, ParentProductName = "Product 2", ChildProductName = "Product 4", GroupId = 1 });
//FullListOfSubscriptions = ListOfSubscriptionsSecond.AddRange(groupedSubscriptions);
FullListOfSubscriptions = groupedSubscriptions
.SelectMany(grp => grp.AsEnumerable())
.Concat(ListOfSubscriptionsSecond); // <<= I'm getting error here
Really depends on what exactly you want to do. Let's say you have a class like below
public class Employee
{
public string Department { get; set; }
public string Name { get; set; }
}
Then you can merge like
public IEnumerable<Employee> Merge(IEnumerable<Employee> employees,
IEnumerable<IGrouping<string, Employee>> employeesByDept)
{
// Just merge all employees
return employeesByDept
.SelectMany(grp => grp.AsEnumerable()) // flatten
.Concat(employees); // concat the other
}
If you want to merge the whole set as IGrouping, there can be many ways of doing that, one of that is just flatten the already grouped one, concat the other list and group again.
public IEnumerable<IGrouping<string, Employee>> MergeGroup(IEnumerable<Employee> employees,
IEnumerable<IGrouping<string, Employee>> employeesByDept)
{
return employeesByDept
.SelectMany(grp => grp.AsEnumerable()) // flatten
.Concat(employees) // concat the other
.GroupBy(e => e.Department); // group again
}
Few thigs to understand here:
IEnumerable is a high level collections interface, which most of the collections (if not all) implement. These are only meant for iteration i.e. going over the collection & reading data. It does not allow modification of any sort.
List is a commonly used implementation of IEnumerable, which is a concrete class AND also supports modification.
A List<T> can be assigned to an IEnumerable<T>, but not vice-versa. Learn about Covariance and Contravariance.
And learn about IGrouping.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
There is the next data structure:
var parents = new List<Parent>
{
new Parent
{
Children = new List<Child>
{
new Child { Name = "Name1", Value = 100 },
new Child { Name = "Name2", Value = 0 },
}
},
new Parent
{
Children = new List<Child>
{
new Child { Name = "Name1", Value = 0 },
new Child { Name = "Name2", Value = 200 },
}
},
new Parent
{
Children = new List<Child>
{
new Child { Name = "Name1", Value = 0 },
new Child { Name = "Name2", Value = 200 },
}
},
new Parent
{
Children = new List<Child>
{
new Child { Name = "Name1", Value = 100 },
new Child { Name = "Name2", Value = 0 },
}
}
};
Parents have the similar children but its values can be binary different (0 or some value).
The output should be:
var output = new List<Child>
{
new Child { Name = "Name1", Value = 100 },
new Child { Name = "Name2", Value = 200 },
};
Is there efficient and compact way to retrieve data in this way via LINQ or extension methods?
Most of the answers are very close but they have small imperfections, in my humble opinion. Here's how I would write it:
var output = parents
.SelectMany(p => p.Children)
.Where(c => c.Value != 0)
.GroupBy(c => c.Name)
.Select(g => g.First())
.ToList();
Maybe I'm misunderstanding but can't you just use SelectMany ?
parents.SelectMany(x=>x.Children).Where(x=>x.Value != 0).Distinct().ToList();
edit: Added .Distinct() per #GSerg's comment
This avoids custom Equality operator or copies of your objects:
parents.SelectMany(p => p.Children).GroupBy(c => c.Name).Select(g => g.FirstOrDefault(c
=> c.Value != 0)).ToList().
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
As example I have the following list of PlanesLogRow objects
public class PlanesLogRow
{
public DateTime ArriveDate;
public string Origin;
public string Destination;
}
Need to get list of all of airports (Origin + Destination).Distinct()
Need to calc for every airport "arrived to airport" and "left from the airport" counts.
I need to create by one LINQ string tuple like <airport, AsOriginCount(arrivedToCount), AsDestinationCount(LeftFromCount)>
To get list of all of airports isn't a problem, but not sure how this can be done in case of such double grouping by different parameters
If you have list of planes you can project each plane object into two anonymous objects - one for destination, and one for origin. Then group these anonymous objects by airport and calculate totals:
planes.SelectMany(p => new[] {
new { Airport = p.origin, IsOrigin = true },
new { Airport = p.destination, IsOrigin = false }
})
.GroupBy(x => x.Airport)
.Select(g => new {
Airport = g.Key,
AsOriginCount = g.Count(x => x.IsOrigin),
AsDestinationCount = g.Count(x => !x.IsOrigin)
})
For given planes:
var planes = new List<Plane> {
new Plane { Origin = "Minsk", Destination = "London" },
new Plane { Origin = "Barcelona", Destination = "Minsk" },
new Plane { Origin = "Rome", Destination = "Minsk" },
new Plane { Origin = "Barcelona", Destination = "London" },
new Plane { Origin = "London", Destination = "Rome" },
};
Output will be:
[
{ "Airport": "Minsk", "AsOriginCount": 1, "AsDestinationCount": 2 },
{ "Airport": "London", "AsOriginCount": 1, "AsDestinationCount": 2 },
{ "Airport": "Barcelona", "AsOriginCount": 2, "AsDestinationCount": 0 },
{ "Airport": "Rome", "AsOriginCount": 1, "AsDestinationCount": 1 }
]
Update: This query will work with Entity Framework. Generated SQL will be big and scary.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
how to convert to lambda:
var source = new Item[]{
new Item { Key = "A", ID = 1, Text = "Hello" },
new Item { Key = "A", ID = 2, Text = "World" },
new Item { Key = "B", ID = 2, Text = "Bar" },
new Item { Key = "B", ID = 1, Text = "Foo" }
};
var results = (from r in source
group r by r.Key.ToString() into g
select new
{
g.Key,
Data = string.Join("", g.OrderBy(s => s.ID).Select(s => s.Text))
});
It is possible to convert?
Thanks for answer
How about this?
var results = source.GroupBy(r => r.Key).Select(g => new
{
g.Key,
Data = string.Join("", g.OrderBy(s => s.ID).Select(s => s.Text))
});