为了账号安全,请及时绑定邮箱和手机立即绑定

将两个序列与其元素交错连接

将两个序列与其元素交错连接

C#
蝴蝶不菲 2022-12-24 12:47:53
我想连接两个序列的元素,生成一个包含原始两个序列的所有元素的单个序列,但它们的元素交错。ConcatLINQ 方法可以进行连接但没有交错,所以我需要一些特别的东西。交错规则如下:对于每对元素,selector应该调用一个函数,并且选择的元素应该是第一个或第二个,具体取决于boolean函数的结果(true:第一个,false:第二个)这是我想要实现的实际示例:var sequence1 = new int[] { 1, 2, 3 };var sequence2 = new int[] { 11, 12, 13 };var result = sequence1.ConcatInterleaved(sequence2, (a, b) => (a + b) % 3 == 0);Console.WriteLine(String.Join("\r\n", result));预期输出:1  // Because (1 + 11) % 3 == 0, the first is selected11 // Because (2 + 11) % 3 != 0, the second is selected12 // Because (2 + 12) % 3 != 0, the second is selected2  // Because (2 + 13) % 3 == 0, the first is selected13 // Because (3 + 13) % 3 != 0, the second is selected3  // Because sequence2 has no more elements, the next element of sequence1 is selected我想要一个 LINQ 解决方案,以便本着内置 LINQ 方法的精神可以推迟实际的串联。这是我目前的尝试:public static IEnumerable<TSource> ConcatInterleaved<TSource>(    this IEnumerable<TSource> source,    IEnumerable<TSource> other,    Func<TSource, TSource, bool> selector){    // What to do?}更新:我更改了示例,因此它看起来不像是简单的交替交错。关于该selector函数的说明:该函数不适用于两个序列的预选对,就像它在Zip方法中发生的那样。这些对不是预定义的。每次选择后都会形成一个新对,其中包含先前选择的拒绝元素和先前选择的序列中的新元素。例如对于选择器(a, b) => truetheConcatInterleaved变得等效于Concat:返回 sequence1 的所有元素,然后是 sequence2 的所有元素。另一个例子:使用选择器(a, b) => false返回 sequence2 的所有元素,然后是 sequence1 的所有元素。
查看完整描述

1 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

public static IEnumerable<T> Weave(

  this IEnumerable<T> left,

  IEnumerable<T> right,

  Func<T, T, bool> chooser)

{

  using(var leftEnum = left.GetEnumerator())

  using(var rightEnum = right.GetEnumerator())

  {

    bool moreLeft = leftEnum.MoveNext;

    bool moreRight = rightEnum.MoveNext;

    while(moreLeft && moreRight)

    {

      if (chooser(leftEnum.Current, rightEnum.Current))

      {

        yield return leftEnum.Current;

        moreLeft = leftEnum.MoveNext();

      }

      else

      {

        yield return rightEnum.Current;

        moreRight = rightEnum.MoveNext();

      } 

    }

    // yield the buffered item, if any

    if (moreLeft) yield return leftEnum.Current;

    if (moreRight) yield return rightEnum.Current;


    // yield any leftover elements

    while (leftEnum.MoveNext()) yield return leftEnum.Current;

    while (rightEnum.MoveNext()) yield return rightEnum.Current;

  }

}


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 113 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号