2013-03-19 3 views
0

В C# вы просто используете SelectMany, у которого есть перегрузка для удержания родительского объекта. Как вы делаете то же самое в F #? То есть, я хочу перебирать набор сборок и возвращать все те сборки, у которых есть классы, реализующие определенный атрибут.Как вы выравниваете набор при сохранении родительского объекта?

Я знаю, что я collect похож на выбор многих, но я не уверен, как его использовать, сохраняя при этом родительскую (сборку) информацию.

+0

Похоже, вы просто хотите, чтобы _filter_ список сборок. Это правильно? – Daniel

+0

По сути, правильно, но как я могу фильтровать без огромного вложенного беспорядка? Это то, что я пытаюсь сделать. – sircodesalot

+0

Связанный: http://stackoverflow.com/questions/4599657/f-list-selectmany/4600047 – gradbot

ответ

1

Вы можете реализовать SelectMany с помощью collect путем применения map к сборнику «детей», которые вы хотите, чтобы вернуться к каждому элементу " родитель»коллекция:

Если у вас есть некоторые source и хотят, чтобы дети с помощью getChildren (для каждого элемента в source), а затем вы хотите, чтобы вычислить результат, используя selectResult, который принимает как ребенок и родитель, вы можете написать следующее с помощью SelectMany:

source.SelectMany 
    ((fun parent -> getChildren parent), 
    (fun parent child -> selectResult parent child)) 

Использования collect тот же код выглядит следующим образом (обратите внимание, что map операции применяется внутри лямбда-функции, которые мы передаем в collect - где parent все еще находится в области видимости):

source |> Seq.collect (fun parent -> 
    getChildren parent 
    |> Seq.map (fun child -> 
     selectResult parent child)) 

стоит также отметить, что поведение захвачена SelectMany может быть реализован - возможно, в более удобном для восприятия способом - с помощью F выражений # последовательности, как это:

seq { for parent in source do 
     for child in getChildren parent do 
      yield selectResult parent child } 
+0

Удивительно, много полезной информации, чтобы учиться здесь. Еще раз спасибо! – sircodesalot

1

Похоже, вам просто нужно filter вместо collect:

let hasTypeWithAttribute<'t when 't :> Attribute> (a: Assembly) = a.GetTypes() |> Array.exists (fun t -> t.GetCustomAttributes(typeof<'t>, true).Length > 0) 

let assemblies = inputSet |> Set.filter hasTypeWithAttribute<AttributeName> 
+0

Серьезно, я потратил на это слишком много времени для такого простого ответа. Хех, спасибо большое! – sircodesalot

Смежные вопросы