代码之家  ›  专栏  ›  技术社区  ›  SuperJMN

如何处理多个可枚举的.Zip调用?

  •  1
  • SuperJMN  · 技术社区  · 6 年前

    经过的时间,速度x,速度y,速度z,高度,纬度,经度

    我想把所有列表的数据组合成一系列状态项。

    class Status 
    {
        public int TimeElapsed {get; set; }
        public double SpeedX {get; set; }
        public double SpeedY {get; set; }
        public double SpeedZ {get; set; }
       ...
    }
    

    我考虑过使用Enumerable.Zip方法,但它看起来非常麻烦:

    var statuses = time_elapsed
        .Zip(speed_x, (a, b) => new { a,  b})
        .Zip(speed_y, (c, d) => new { c,  d})
        .Zip(speed_z, (e, f) => new { e , f})
        .Select(x => new Status
        {
            Time = x.e.c.a,
            SpeedX = x.e.c.b,
            SpeedY = x.e.d,
            SpeedZ = x.f
            // ...
        });
    

    正如你所看到的,它来自于所有那些匿名类型的可读性。

    有没有更好的方法不失去理智?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Tim Schmelter    6 年前

    var statuses = time_elapsed
        .Zip(speed_x, (time, speedX) => new {time, speedX})
        .Zip(speed_y, (x, speedY) => new {x.time, x.speedX, speedY})
        .Zip(speed_z, (x, speedZ) => new Status
        {
            TimeElapsed = x.time,
            SpeedX = x.speedX,
            SpeedY = x.speedY,
            SpeedZ = speedZ
        });
    

    您也可以使用这种方法:

    int minSize = new IList[] {time_elapsed, speed_x, speed_y, speed_z}.Min(c => c.Count);
    IEnumerable<Status> statuses = Enumerable.Range(0, minSize)
        .Select(i => new Status
        {
            TimeElapsed = time_elapsed[i],
            SpeedX = speed_x[i],
            SpeedY = speed_y[i],
            SpeedZ = speed_z[i],
        });
    
        2
  •  1
  •   MikeJ    6 年前

        static IEnumerable<TResult> Zip<TFirst, TSecond, TThird, TResult>(
        IEnumerable<TFirst> first,
        IEnumerable<TSecond> second,
        IEnumerable<TThird> third,
        Func<TFirst, TSecond, TThird, TResult> resultSelector)
        {
            using (IEnumerator<TFirst> iterator1 = first.GetEnumerator())
            using (IEnumerator<TSecond> iterator2 = second.GetEnumerator())
            using (IEnumerator<TThird> iterator3 = third.GetEnumerator())
            {
                while (iterator1.MoveNext() && iterator2.MoveNext() && iterator3.MoveNext())
                {
                    yield return resultSelector(iterator1.Current, iterator2.Current, iterator3.Current);
                }
            }
        }