我正在使用LINQ:
List<String> listA = new List<string>{"a", "b", "c", "d", "e", "f", "g"};
List<String> listB = new List<string>{"1", "2", "3"};
所需结果:
{"a", "1", "b", "2", "c", "3", "d", "1", "e", "2", "f", "3", "g", "1"}
我尝试但失败了:
var mix = ListA.Zip(ListB, (l1, l2) => new[] { l1, l2 }).SelectMany(x => x);
//Result : {"a", "1", "b", "2", "c", "3"}
var mix = ListA.Zip(ListB, (a, b) => new[] { a, b })
.SelectMany(x => x)
.Concat(ListA.Count() < ListB.Count() ? ListB.Skip(ListA.Count()) : ListA.Skip(ListB.Count()))
.ToList();
//Result : {"a", "1", "b", "2", "c", "3", "d", "e", "f", "g"}
如何使用LINQ做到这一点?
答案 0 :(得分:9)
这行得通,即使我不确定为什么您需要它作为linq表达式:
var mix = Enumerable
.Range(0, Math.Max(listA.Count, listB.Count))
.Select(i => new[] { listA[i % listA.Count], listB[i % listB.Count] })
.SelectMany(x => x);
答案 1 :(得分:2)
如何实施您自己的Zip版本?
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO
{
internal class Program
{
public static void Main(string[] args)
{
List<String> listA = new List<string> {"a", "b", "c", "d", "e", "f", "g"};
List<String> listB = new List<string> {"1", "2", "3"};
var mix = listA.ZipNew(listB, (l1, l2) => new[] {l1, l2}).SelectMany(x => x);
foreach (var m in mix)
{
Console.WriteLine(m);
}
}
}
public static class Impl
{
public static int A(this int a)
{
return 1;
}
public static IEnumerable<TResult> ZipNew<TFirst, TSecond, TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> iterator1 = first.GetEnumerator())
using (IEnumerator<TSecond> iterator2 = second.GetEnumerator())
{
var i1 = true;
var i2 = true;
var i1Shorter = false;
var i2Shorter = false;
var firstRun = true;
while(true)
{
i1 = iterator1.MoveNext();
i2 = iterator2.MoveNext();
if (!i1 && (i1Shorter || firstRun))
{
iterator1.Reset();
i1 = iterator1.MoveNext();
i1Shorter = true;
firstRun = false;
}
if (!i2 && (i2Shorter || firstRun))
{
iterator2.Reset();
i2 = iterator2.MoveNext();
i2Shorter = true;
firstRun = false;
}
if (!(i1 && i2))
{
break;
}
yield return resultSelector(iterator1.Current, iterator2.Current);
}
}
}
}
}
答案 2 :(得分:2)
到目前为止,只有一种版本尝试做正确的事情并使用正确的方法,这是BWA提出的版本。可以对此扩展进行一些简化,因此我将其留在此处以供参考:
public static IEnumerable<TResult> ZipLoop<TFirst, TSecond, TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
if (first is null) throw new ArgumentNullException(nameof(first));
if (second is null) throw new ArgumentNullException(nameof(second));
if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
var (firstCycle, secondCycle) = (false, false);
var e1 = first.GetEnumerator();
var e2 = second.GetEnumerator();
try
{
while (true)
{
if (!TryMoveNextOrLoop(first, ref e1, ref firstCycle)) yield break;
if (!TryMoveNextOrLoop(second, ref e2, ref secondCycle)) yield break;
if (firstCycle && secondCycle) yield break;
yield return resultSelector(e1.Current, e2.Current);
}
}
finally
{
e1?.Dispose();
e2?.Dispose();
}
}
private static bool TryMoveNextOrLoop<T>(IEnumerable<T> source, ref IEnumerator<T> enumerator, ref bool cycle)
{
if (!enumerator.MoveNext())
{
cycle = true;
enumerator.Dispose();
enumerator = source.GetEnumerator();
return enumerator.MoveNext();
}
return true;
}
答案 3 :(得分:0)
您非常接近(一个)答案。怎么样?
var listA = new List<string> { "a", "b", "c", "d", "e", "f", "g" };
var listB = new List<string> { "1", "2", "3" };
// "a", "b", "c", "d", "e", "f", "g", "a", "b", "c", "d", "e", "f", "g", etc.
// This is lazily evaluated so it doesn't matter that there are
// more elements than needed here.
var repeatedA = Enumerable.Repeat(listA, listB.Count)
.SelectMany(list => list);
// "1", "2", "3", "1", "2", "3", etc. This is lazily evaluated
// so it doesn't matter that there are more elements than needed here.
var repeatedB = Enumerable.Repeat(listB, listA.Count)
.SelectMany(list => list);
var result = repeatedA.Zip(repeatedB, (a, b) => new[] { a, b })
.SelectMany(x => x)
.Take(2 * Math.Max(listA.Count, listB.Count));
// result is {"a", "1", "b", "2", "c", "3", "d", "1", "e", "2", "f", "3", "g", "1"}
答案 4 :(得分:0)
我会采用List<String> listA = new List<string> { "a", "b", "c", "d", "e", "f", "g" };
List<String> listB = new List<string> { "1", "2", "3" };
List<string> listC = new List<string>();
for (int i = 0; i < Math.Max(listA.Count, listB.Count); i++)
{
listC.Add(listA[i % listA.Count]);
listC.Add(listB[i % listB.Count]);
}
循环方法
handleResize = e => {
if (this.state.navHidden === false && window.outerWidth > 500) {
this.setState({ hidden: true })
} else if (this.state.navHidden === true && window.outerWidth <= 500) {
this.setState({ hidden: false })
}
}
答案 5 :(得分:0)
如何?
listA.SelectMany((a, i) => new[] { a, listB[i % listB.Count]})
答案 6 :(得分:-1)
尝试一下...
var mix =Enumerable.Range(0, new[] { listA.Count, listB.Count }.Max()).Select(i => new[] { listA[i % listA.Count], listB[i % listB.Count] }).SelectMany(x => x);