Один из способов сделать это - объединить Enumerable.Zip
и Enumerable.Aggregate
вместе с немного ловушкой . Обратите внимание, что все еще использует петли под капотом.
var aList = aEven.Zip(aOdd, (even, odd) => new {even, odd})
.Aggregate(new List<int>(aEven.Length + aOdd.Length),
(list, z) =>
{
list.Add(z.even);
list.Add(z.odd);
return list;
});
if (aEven.Length != aOdd.Length)
aList.Add(aEven[aEven.Length-1]);
var aOutput = aList.ToArray();
for (var i = 0; i < aOutput.Length; ++i)
Console.WriteLine($"aOutput[{i}] ==> {aOutput[i]} == {a[i]} <== a[{i}]");
Однако это работает только в вашем сценарии (разделение, а затем восстановление массива по нечетным / четным индексам , при условии, что порядок «подмассивов» был сохранен ).
Результирующие массивы будут иметь одинаковый размер (исходный массив имел четное количество элементов) или четный массив будет иметь один дополнительный элемент (исходный массив имел нечетное количество элементов). В последнем случае дополнительный предмет будет отброшен на Zip
и должен быть учтен вручную. Это не будет работать для других сценариев, где ваши два подмассива были рассчитаны другими способами.
Вы также можете сделать это без промежуточного списка, используя предварительно выделенный массив, но вам придется отслеживать индекс вне вызовов LINQ (что мне не очень нравится):
var index = 0;
var aOutput = aEven.Zip(aOdd, (even, odd) => new {even, odd})
.Aggregate(new int[aEven.Length + aOdd.Length],
(arr, z) =>
{
arr[index++] = z.even;
arr[index++] = z.odd;
return arr;
});
if (aEven.Length != aOdd.Length)
aOutput[index] = aEven[aEven.Length-1];
Еще один способ сделать это - использовать комбинацию Zip
, SelectMany
и Concat
(для учета последнего элемента):
var aOutput = aEven.Zip(aOdd, (even, odd) => new[]{ even, odd })
.SelectMany(z => z)
.Concat(aEven.Length == aOdd.Length ? new int[0] : new []{ aEven[aEven.Length - 1] })
.ToArray();
Простой цикл for, вероятно, все еще будет самым простым решением.