我正在尝试按特定字段对对象列表进行分组。
稍后,我需要按如下方式使用此列表:
for(i=0; i< list.Count; i++)
{
if(i == 0)
continue;
if (list[i].property != list[i-1].property)
dosomething;
}
我需要做一个for循环,所以我可以说“如果该项目的属性在此之前是不同的......
当我尝试订购列表时出现问题。如果我做list.GroupBy,我无法访问列表项的成员。如果我做list.OrderBy,我必须将它设置为一个ienumerable,因此不能使用for循环,因为ienumerables不适用于列表索引。
有没有办法在foreach循环中实现此功能(不引用索引)?如果没有,是否有其他方式来订购我的列表,不需要将其设置为不可数?
答案 0 :(得分:3)
四个选项:
OrderBy
然后ToList
获取排序列表。然后你可以使用你现有的代码,虽然我建议在1开始循环而不是从0开始并在第一次迭代中立即断开。使用OrderBy
然后Zip
:
var ordered = input.OrderBy(...);
var zipped = ordered.Zip(ordered.Skip(1),
(Previous, Current) => new { Previous, Current });
foreach (var pair in zipped)
{
if (pair.Previous.Property == pair.Current.Property)
{
... Whatever you want to do
}
}
请注意,遗憾的是,这会对输入进行两次排序。没有内置的避免方法(不调用ToList
或其他)。不可否认,写一个“自我拉链”扩展方法并不难。
使用OrderBy
并保留“之前的属性”:
var ordered = input.OrderBy(...);
// This is like using foreach, but with a simple way to get the
// first item
using (var iterator = ordered.GetEnumerator())
{
if (!iterator.MoveNext())
{
return; // Or whatever. No items!
}
var previousProperty = iterator.Current.Property;
while (iterator.MoveNext())
{
var currentProperty = iterator.Current.Property;
if (previousProperty == currentProperty)
{
... Whatever you want to do
}
previousProperty = currentProperty;
}
}
使用List<T>.Sort
答案 1 :(得分:0)
您可以在循环之前定义myitem previous
(其中myitem
在列表中的类型相同),然后在每个列表的末尾,将previous
设置为当前项目。如果您这样做,请务必检查previous
是否为null,因为它第一次没有值。
答案 2 :(得分:0)
这只是Skeet的一个选项的重复。给他支票。
ForEach不需要索引。无法使用ForEach从列表中删除项目。
class Program
{
static void Main(string[] args)
{
List<SortMe> SortMes = new List<SortMe>();
SortMes.Add(new SortMe("aaa"));
SortMes.Add(new SortMe("bbb"));
SortMes.Add(new SortMe("ccc"));
SortMes.Add(new SortMe("aaa"));
SortMes.Add(new SortMe("bbb"));
SortMes.Add(new SortMe("ccc"));
SortMes.Add(new SortMe("ccc"));
SortMes.Add(new SortMe("bbb"));
SortMes.Add(new SortMe("aaa"));
SortMes.Add(new SortMe("ccc"));
SortMes.Add(new SortMe("bbb"));
SortMes.Add(new SortMe("aaa"));
SortMe SortMeLast = null;
foreach (SortMe SortMeCurrent in SortMes.OrderBy(x => x.Name))
{
Console.WriteLine(" Current " + SortMeCurrent.Name);
if (SortMeLast != null)
{
if (SortMeCurrent.Name != SortMeLast.Name)
{
// do something
Console.WriteLine("Do Something");
}
}
SortMeLast = SortMeCurrent;
}
Console.ReadLine();
}
}
public class SortMe
{
public string Name { get; set; }
public SortMe(string name) { Name = name; }
}