C# 将两个序列连接在一起,且其元素交错
我想连接两个序列的元素,生成一个包含原始两个序列的所有元素的序列,但是它们的元素交错 LINQ方法可以进行串联,但没有交错,所以我需要一些特殊的东西 交织规则如下:C# 将两个序列连接在一起,且其元素交错,c#,linq,C#,Linq,我想连接两个序列的元素,生成一个包含原始两个序列的所有元素的序列,但是它们的元素交错 LINQ方法可以进行串联,但没有交错,所以我需要一些特殊的东西 交织规则如下: 对于每对元素,应调用一个选择器函数,所选元素应为第一个或第二个,具体取决于函数的布尔值结果(true:first,false:second) 以下是我想要实现的一个实际例子: var sequence1 = new int[] { 1, 2, 3 }; var sequence2 = new int[] { 11, 12, 13
- 对于每对元素,应调用一个
函数,所选元素应为第一个或第二个,具体取决于函数的选择器
结果(布尔值
:first,true
:second)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 selected
11 // Because (2 + 11) % 3 != 0, the second is selected
12 // Because (2 + 12) % 3 != 0, the second is selected
2 // Because (2 + 13) % 3 == 0, the first is selected
13 // Because (3 + 13) % 3 != 0, the second is selected
3 // 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?
}
公共静态IEnumerable concatterleaved(
这是一个数不清的来源,
我是数不清的其他人,
Func选择器)
{
//怎么办?
}
更新:我更改了示例,使其看起来不像简单的交替交错 关于
选择器
函数的说明:该函数不适用于两个序列的预选对,就像在方法中发生的那样。这些对不是预定义的。每次选择后,形成一对新的元素对,其中包含先前选择的被拒绝元素和先前选择序列中的新元素
例如,使用选择器(a,b)=>true
时,ConcatInterleaved
变得等效于Concat
:返回sequence1的所有元素,然后是sequence2的所有元素。另一个示例:使用选择器(a,b)=>false
返回sequence2的所有元素,然后是sequence1的所有元素。公共静态IEnumerable(
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;
}
}
这是一个数不清的左边,
我数不清的权利,
函数选择器)
{
使用(var leftEnum=left.GetEnumerator())
使用(var rightEnum=right.GetEnumerator())
{
bool moreLeft=leftEnum.MoveNext;
bool moreRight=rightEnum.MoveNext;
while(更多左和更多右)
{
if(选择器(leftEnum.Current、rightEnum.Current))
{
返回leftEnum.Current;
moreLeft=leftEnum.MoveNext();
}
其他的
{
收益返回rightEnum.Current;
moreRight=rightEnum.MoveNext();
}
}
//产生缓冲项(如果有)
如果(moreLeft)产生返回leftEnum.Current;
如果(moreRight)返回rightEnum.Current;
//产生任何剩余元素
而(leftEnum.MoveNext())则返回leftEnum.Current;
而(rightEnum.MoveNext())则返回rightEnum.Current;
}
}
Theodor,这既不是交错也不是压缩。选择器的用途是什么?只需从每个列表中选择一项,即可产生所需的输出。这已经实现了,例如在operator中。@PanagiotisKanavos yeap,我知道如何按程序实现。我不知道如何用LINQ风格(使用可枚举项)来做。怎么做?这不是交错的。选择器的用途是什么?至于LINQ样式
,这就是LINQ所做的。复制显示了如何以惰性和昂贵的方式交错枚举-使用Zip
对值进行配对,然后SelectMany
将配对转换为小的枚举。MoreLinq的方法很快——从每个枚举器中选择一个项并生成它。它们都是LINQ
y,都使用可枚举项<代码>可枚举。Concat的工作方式与此相同。那么在哪里
或选择
,它们都可以与enumerators@PanagiotisKanavos我看了MoreLinq的Interleave
。它不符合我的要求。对交织过程没有控制权。我想一对一对地控制交织。