2013-06-27 3 views
1

У меня есть набор элементов, которые я хочу преобразовать (в основном, обернуть в метаданные). Для первого элемента в коллекции я просто обертываю необходимые метаданные вокруг элемента, и все готово. Метаданные второго элемента зависят от метаданных предыдущего элемента, поэтому я хочу передать метаданные первого элемента ко второму элементу.Подача текущего элемента в следующий элемент в запросе LINQ

Следующая ....

object[] A; 

A.skip(1) 
.Zip(A, (first, second), a => new Metadata(first, second)); 

... не будет работать, потому что он использует object как второй вход, а не Metadata. Это верно для любого другого решения, которое я видел до сих пор (передача исходного объекта, а не результат функции Select()).

Как я могу передать результат Select() для первого элемента в моем запросе LINQ в Select() для второго элемента?

Я знаю, что я мог бы использовать цикл for, чтобы выполнить это, но мне интересно, нет ли более функционального способа решения этой проблемы. Должно быть решение в языках функционального стиля, таких как F #, и мне интересно, могу ли я перевести это в решение LINQ на C#. Решение с одним вкладышем было бы особенно удивительным.

Объединив метаданные вместе, я могу передать важную информацию из одного элемента во все следующие элементы, такие как флаги или контекст. Цель, в конечном счете, состоит не только в том, чтобы знать о предыдущем элементе, но и во всем контексте текущего элемента. Текущий пункт может затем изменить контекст для всех следующих элементов и т. Д.

ответ

1

Такое поведение обычно выполняется с помощью scan или аналогичной функции в функциональных языках программирования. В F #, вы можете сделать это следующим образом:

originalSequence |> Seq.scan (fun (prev, current) -> Some <| new Metadata((* ... stuff ... *))) None 

См this question для реализации метода Scan расширения в C#. Учитывая, что метод, вы можете реализовать свой запрос так:

A.Scan((previous, current) => new Metadata(/* ... */), null) 

не может думать о шикарной реализации Однострочника метода Scan хотя.

+0

Спасибо! Если вам интересно, я применил эту функцию к [этому вопросу/ответу] (http://stackoverflow.com/a/17345950/211627). – JDB

+0

@ Cyborgx37, хорошо! – MisterMetaphor

1

Попробуйте .Aggregate().

var data = A.Aggregate(new Metadata(null, A), (meta, a) => new Metadata(meta, a)); 

Я не гарантирую, что у меня есть синтаксис для этого права, особенно для вашего кода. Однако идея должна быть ясной, и если вы редактируете более подробный пример, я могу расширить это.

+0

Я думаю, что это правильно, за исключением того, что это даст только последнее значение последовательности. – MisterMetaphor

+0

@MisterMetaphor - есть [другая версия] (http://msdn.microsoft.com/en-us/library/bb548744.aspx), которая принимает дополнительный аргумент для функции для получения результата. Это может быть то, что нужно. Кроме того, спасибо за ловушку «Накопление» -> «Агрегат». Я всегда это делаю. – Bobson

+0

Вы можете видеть из сигнатуры метода, что она возвращает одно значение. Я могу ошибаться, но я думаю, что OP пытается получить последовательность элементов в результате. – MisterMetaphor