迭代行

时间:2016-06-28 13:46:07

标签: c#

myClass结构:

public class myClass
    {
        public string Name { get; set; }
        public string AdditionalData { get; set; }
        public System.DateTime ActivityTime { get; set; }
    }

我有一个上面列出的列表,所有按活动时间排序的行列说'行为'。

我希望将我的数据转换为以下类的列表..

public class newClass
    {
        public string Name { get; set; }
        public string AdditionalData { get; set; }
        public System.DateTime StartTime { get; set; }
    public System.DateTime EndTime { get; set; }
    }

这里的StartTime与prev class的ActivityTime具有相同的值,所以我没有问题。 但是EndTime应该具有下一个列表对象的ActivityTime值,这个我无法知道如何获取.. 最后一个列表对象的EndTime可以与starttime相同

所以我的代码是..

List<newClass> items = new List<newClass>();
foreach (var item in acts)
{

            newClass si = new newClass
                        {
                            Name=item.Name,
                AdditionalData=item.AdditionalData,
                StartTime = item.ActivityTime ,
                EndTime = //what do I do here??????

                        };
                        items.Add(si);

}

真心感谢任何帮助

3 个答案:

答案 0 :(得分:4)

在移动到该位置之前,无法访问下一个迭代器值。

您可以在这里做的是记住上一个项目并在下一个循环中更新它。假设对于最后一个元素,它应该是空的,它将如下所示:

List<newClass> items = new List<newClass>();
newClass last = null;
foreach (var item in acts) {
        // update the last element here:
        if (last != null)
            last.EndTime = item.ActivityTime;
        newClass si = new newClass
                    {
                        Name=item.Name,
                        AdditionalData=item.AdditionalData,
                        StartTime = item.ActivityTime ,
                        //EndTime = null; // will be updated in the next loop
                    };
        last = si;
        items.Add(si);

}

// handle the last item (if needed):
if (last != null)
     last.EndTime = ... // special value for last item

答案 1 :(得分:3)

我有一个比for-loop更优雅的解决方案:

        List<newClass> output = acts.Select((a, index) => new newClass()
        {
            Name = a.Name,
            AdditionalData = a.AdditionalData,
            StartTime = a.ActivityTime,
            EndTime = (index + 1 < acts.Count) ? acts[index + 1].ActivityTime : default(DateTime)
        }).ToList();

或者您可以使用for循环而不是foreach:

List<newClass> items = new List<newClass>();
// assuming length > 0
int length = (acts.Length  % 2 == 0) ? acts.Length : acts.Length - 1;
for (int i = 0; i < acts.Length; i++)
{
    newClass si = new newClass
    {
        Name=acts[i].Name,
        AdditionalData=acts[i].AdditionalData,
        StartTime = acts[i].ActivityTime ,
        EndTime = acts[i+1].ActivityTime
    };
    items.Add(si);  
}

if (length < acts.Length)
  // handle the last element as you wish

答案 2 :(得分:0)

如果您想使用LINQ,您可以创建一个扩展方法,例如......

public static class EnumerableEx
{
    public static IEnumerable<Tuple<T, T>> WithNext<T>(this IEnumerable<T> items)
    {
        var e = items.GetEnumerator();
        bool r = e.MoveNext();
        if (!r)
            yield break;
        do
        {
            T last = e.Current;
            var item = (r = e.MoveNext()) ? e.Current : default(T);
            yield return Tuple.Create(last, item);
        } while (r);
    }
}

...这是一个如何使用它的例子......

class Program
{
    static void Main(string[] args)
    {
        var i = new int?[] { 1, 2, 3 };
        foreach (var n in i.WithNext())
            //the last value will be paired with a null.  
            // you can use null coalesce to fill in the missing item.
            Console.WriteLine("{0} => {1}", n.Item1, n.Item2 ?? 9);

        /*
            1 => 2
            2 => 3
            3 => 9
         */
    }
}