C# LINQ 组按属性集合,然后按列表定义的显式顺序对每个组进行排序[重复]
Posted
技术标签:
【中文标题】C# LINQ 组按属性集合,然后按列表定义的显式顺序对每个组进行排序[重复]【英文标题】:C# LINQ group collection by attribute then sort each group by explicit order defined by a list [duplicate] 【发布时间】:2021-11-15 18:52:23 【问题描述】:我有一组我想要的 C# 对象
-
给定属性的分组
然后按另一个属性对每个组进行排序。
排序顺序由列表明确定义。
然后我只想从每个组中获取最上面的项目
例如,考虑:
data = [
"name": "Alice", "country": "UK", "age": 30,
"name": "Bob", "country": "KE", "age": 20,
"name": "Charlie", "country": "UK", "age": 30,
"name": "Alice", "country": "KE", "age": 40,
"name": "Bob", "country": "AU", "age": 50,
"name": "David", "country": "USA", "age": 25,
]
我想按name
分组,然后按country
对每个组进行排序,以遵循另一个集合中指定的明确顺序,例如:
var countryOrder = new List<string> "UK", "KE", "AU", "USA";
然后我想根据这个顺序只选择每个组的***成员,这样我最终会得到一个名称唯一的对象列表(例如,UK
、KE
中的一个Alice
, AU
或 USA
) 但遵循明确定义的优先顺序。
以下是给定示例的预期输出:
output = [
"name": "Alice", "country": "UK", "age": 30,
"name": "Bob", "country": "KE", "age": 20,
"name": "Charlie", "country": "UK", "age": 30,
"name": "David", "country": "USA", "age": 25,
]
我已尝试使用以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
public static void Main()
var countryOrder =new List<string> "UK", "KE", "AU", "USA";
var data = new List<ExampleDataClass>
new ExampleDataClass Name = "Alice", Country = "UK", Age = 30 ,
new ExampleDataClass Name = "Bob", Country = "KE", Age = 20 ,
new ExampleDataClass Name = "Charlie", Country = "UK", Age = 30 ,
new ExampleDataClass Name = "Alice", Country = "KE", Age = 40 ,
new ExampleDataClass Name = "Bob", Country = "AU", Age = 50 ,
new ExampleDataClass Name = "David", Country = "USA", Age = 25
;
var reducedData = data
.GroupBy(x => x.Name)
.Select(g => g.OrderBy(item => countryOrder.IndexOf(item.Country)).Min())
.ToList();
reducedData.ForEach(item => Console.WriteLine(reducedData));
class ExampleDataClass
public string Name get; set;
public string Country get; set;
public int Age get; set;
.Select(g => g.OrderBy(item => countryOrder.IndexOf(item.Country)).Min())
给出运行时异常:
Run-time exception (line 50): At least one object must implement IComparable.
Stack Trace:
[System.ArgumentException: At least one object must implement IComparable.]
at System.Collections.Comparer.Compare(Object a, Object b)
at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
at System.Linq.Enumerable.Min[TSource](IEnumerable`1 source)
at Program.<>c__DisplayClassd.<Main>b__9(IGrouping`2 g) :line 50
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Program.Main() :line 49
【问题讨论】:
data
是一个JSON数组是否正确?
将其作为 C# 对象的集合处理
data.GroupBy(g => g.name).Select(g => new group = g.Key, items = g.OrderBy(g => g.country)); - 类似这样,但您需要考虑 OrderBy 上的国家/地区收集
您应该尝试解决手头的问题,而不仅仅是告诉我们您想要得到什么。
@Flater 我已经输入了代码尝试和预期的输出
【参考方案1】:
这是我找到的解决方案:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
public static void Main()
var countryOrder =new List<string> "UK", "KE", "AU", "USA";
var data = new List<ExampleDataClass>
new ExampleDataClass
Name = "Alice",
Country = "UK",
Age = 30,
,
new ExampleDataClass
Name = "Bob",
Country = "KE",
Age = 20,
,
new ExampleDataClass
Name = "Charlie",
Country = "UK",
Age = 30,
,
new ExampleDataClass
Name = "Alice",
Country = "KE",
Age = 40,
,
new ExampleDataClass
Name = "Bob",
Country = "AU",
Age = 50,
,
new ExampleDataClass
Name = "David",
Country = "USA",
Age = 25,
;
var reducedData = data.GroupBy(x => x.Name)
.Select(g => g.OrderBy(item => countryOrder.IndexOf(item.Country)).First())
.ToList();
foreach (ExampleDataClass item in reducedData)
Console.WriteLine(string.Format("Name: \"0\", Country: \"1\", Age: 2", item.Name, item.Country, item.Age));
class ExampleDataClass
public string Name get; set;
public string Country get; set;
public int Age get; set;
输出
Name: "Alice", Country: "UK", Age: 30
Name: "Bob", Country: "KE", Age: 20
Name: "Charlie", Country: "UK", Age: 30
Name: "David", Country: "USA", Age: 25
链接到 dotnetfiddle https://dotnetfiddle.net/6geHtk
【讨论】:
以上是关于C# LINQ 组按属性集合,然后按列表定义的显式顺序对每个组进行排序[重复]的主要内容,如果未能解决你的问题,请参考以下文章