Здравствуйте, coddy, Вы писали:
C>Возможно ли средствами LINQ решить такую задачу:
C>Получить элементы списка, со значением "2" и у рядом с которыми есть пустые элементы (т.е. со значением "0")
Оно?
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2 {
public static class ZipHelper {
public static IEnumerable<W> Zip3<T, U, V, W>(IEnumerable<T> seq1, IEnumerable<U> seq2, IEnumerable<V> seq3, Func<T, U, V, W> resultSelector) {
using (var enum1 = seq1.GetEnumerator())
using (var enum2 = seq2.GetEnumerator())
using (var enum3 = seq3.GetEnumerator()) {
while (enum1.MoveNext() && enum2.MoveNext() && enum3.MoveNext()) {
yield return resultSelector(enum1.Current, enum2.Current, enum3.Current);
}
}
}
}
class Program {
static void Main() {
var points = new[] {
new { X = 1, Y = 2, Z = 3, Turn = 0},
new { X = 2, Y = 3, Z = 4, Turn = 0},
new { X = 3, Y = 4, Z = 5, Turn = 2},
new { X = 4, Y = 5, Z = 6, Turn = 0},
new { X = 5, Y = 6, Z = 7, Turn = 0},
new { X = 6, Y = 7, Z = 8, Turn = 2},
new { X = 7, Y = 8, Z = 9, Turn = 0},
new { X = 8, Y = 9, Z = 0, Turn = 0},
new { X = 9, Y = 0, Z = 1, Turn = 2},
};
var q =
from triple in ZipHelper.Zip3(points, points.Skip(1), points.Skip(2), (l, m, r) => new { l, m, r })
where triple.m.Turn == 2 && triple.l.Turn == 0 && triple.r.Turn == 0
select triple.m;
foreach (var p in q) {
Console.WriteLine(p);
}
}
}
}
Здравствуйте, coddy, Вы писали:
C>Возможно ли средствами LINQ решить такую задачу:
C>Получить элементы списка, со значением "2" и у рядом с которыми есть пустые элементы (т.е. со значением "0")
Уже предложили перенести функцию zip из функциональных языков, можно портировать еще и window, которая создаёт плавающее окно заданного размера:
public static IEnumerable<IEnumerable<T>> Window<T>(this IEnumerable<T> self, int windowSize)
{
int index = 0;
var window = new List<T>(windowSize);
window.AddRange(new T[windowSize]);
foreach (var item in self)
{
bool initializing = index < windowSize;
if (!initializing)
{
window = window.Skip(1).ToList();
window.Add(default(T));
}
int itemIndex = initializing ? index : windowSize - 1;
window[itemIndex] = item;
index++;
bool initialized = index >= windowSize;
if (initialized)
yield return new List<T>(window);
}
}
Тогда задача решается примерно таким кодом:
var q =
from triple in points.Window(3)
let arr = triple.ToArray()
where arr[1].Turn == 2 && arr[0].Turn == 0 && arr[2].Turn == 0
select arr[1];
Функцию Window() я написал не сам, а нашёл в библиотеке
Cadenza, где и аналог Zip3() тоже есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1419>>