我正在尝试对一组对象进行分组,按名称排序,但我还想在每个组中设置一个顺序的InstanceID属性,以便我有以下内容:
Name="A", InstanceID=0
Name="A", InstanceID=1
Name="A", InstanceID=2
Name="B", InstanceID=0
Name="C", InstanceID=0
Name="C", InstanceID=1
Name="C", InstanceID=2
Name="D", InstanceID=0
Name="D", InstanceID=1
Name="D", InstanceID=2
Name="D", InstanceID=3
等
我假设在GroupBy
之后通过LINQ应用了一些投影但我不知道如何在Select
或SelectMany
中使用累加器或索引
我不想创建新集合,只修改现有集合,在每个元素上设置InstanceID
。
答案 0 :(得分:4)
您可以GroupBy
Name
,然后为每个组设置InstanceID
属性:
var groups = objects.GroupBy(m => m.Name);
foreach (var group in groups)
{
int index = 0;
foreach (var item in group)
item.InstanceID = index++;
}
修改强>
您可以创建接收项目和索引的扩展方法ForEach
:
static class Extensions
{
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
action(item);
}
public static void ForEach<T>(this IEnumerable<T> collection, Action<T, int> action)
{
int index = 0;
foreach (var item in collection)
action(item, index++);
}
}
并像这样使用它:
var groups = objects.GroupBy(m => m.Name);
groups.ForEach(g => g.ForEach((o, i) => o.InstanceID = i));
答案 1 :(得分:3)
您可以使用GroupBy
,然后使用投射该索引的Select
重载:
var groups = objects
.GroupBy(x => x.Name)
.Select(g => g.Select((obj, index) => new { Object = obj, Index = index }));
foreach(var grp in groups)
foreach(var x in grp)
x.Object.InstanceID = x.Index;
如果您对这些群组并不感兴趣,并且在确定索引后想要展平它们,您还可以使用SelectMany
和一个循环:
var items = objects
.GroupBy(x => x.Name)
.SelectMany(g => g.Select((obj, index) => new { Object = obj, Index = index }));
foreach(var x in items)
x.Object.InstanceID = x.Index;
答案 2 :(得分:2)
选择的重载会为您提供索引
var list = otherList.Select((model, index) => new { Index=index, ... })
在你的情况下,它可以像这样使用
list = list
.OrderBy(m => m.Name)
.GroupBy(m => m.Name)
.SelectMany(g => g.Select((m, i) => new NameOfClass { InstanceID = i, Name = m.Name } ))
.ToList();
答案 3 :(得分:0)
为了简单起见,我会使用这样的类:
public class StudentSubject
{
public string Subject { get; set; }
public string Student { get; set; }
public int ID { get; set; }
}
列表必须以某种方式填充:
var list = new List<StudentSubject>();
list.Add(new StudentSubject
{
Subject = "Physics",
Student = "Steve"
});
list.Add(new StudentSubject
{
Subject = "Physics",
Student = "Sarah"
});
....
然后遍历列表:
var subjectGroups = from subjectStudent in list
group subjectStudent by subjectStudent.Subject;
foreach(var subjectNameGroup in subjectGroups)
{
int id = 0;
foreach (var studentSubject in subjectNameGroup)
{
studentSubject.ID = id;
id++;
}
}
答案 4 :(得分:0)
使用查询表达式的解决方案:
class Person
{
public string Name {get; set;}
public int Instance {get; set;}
}
Person p1 = new Person {Name ="C"};
Person p2 = new Person {Name ="B"};
Person p3 = new Person {Name ="A"};
Person p4 = new Person {Name ="C"};
Person p5 = new Person {Name ="C"};
Person p6 = new Person {Name ="B"};
var persons = new List<Person>{p1, p2, p3, p4, p5, p6};
var result = from p in persons
group p by p.Name into g orderby g.Key
from gr in g.Select((x,i) => new {Value = x, Index = i})
select gr;
result.ToList().ForEach(x => x.Value.Instance = x.Index);