2016-11-17 4 views
0

У меня есть довольно простая .NET-логика, которую я пересаживаю в кодовую базу Scala, и я не знаю в первую очередь о Scala. Она включает в себя запрос LINQ, что группы коллекцию помеченных объектов путем использования анонимного проекционного типа выравниваться и присоединиться, а затем группировки, например:LINQ SelectMany эквивалент в Scala

var q = things.SelectMany(t => t.Tags, (t, tag) => new { Thing = t, Tag = tag }) 
       .GroupBy(x => x.Tag, x => x.Thing); 

В Scala выглядит как flatMap может быть полезна, но Я не могу понять, как объединить его с groupBy через анонимный.

Это что-то еще более сложное в Scala, или я пропустил что-то простое?

UPDATE:

Я закончил тем, что шел с:

things.flatMap(t => t.Tags.map(x => (x,t))).groupBy(x => x._1) 

, а затем, конечно, позже, когда я доступ к значениям в карте, что нужно сделать:

.map(x => x._2) 

в выведите группы из кортежа.

Простой, когда вы знаете как!

+0

Я не выполняю именно то, что вы хотите выполнить, можете ли вы исправить свой пример C#. SelectMany принимает только один вход (кроме параметра расширения 'this'), и у вас, похоже, два. Кроме того, ваши круглые скобки не сбалансированы, и вам сложно понять, куда вы их намеревались. – Danny

+0

Я вижу, что вы добавили отсутствующую скобку, но у вашего 'SelectMany' слишком много аргументов источник и метод выбора https://msdn.microsoft.com/en-us/library/bb534336(v=vs.110).aspx, но вы, кажется, предоставляете два метода: – Danny

+0

Простите, пропустил одиннадцатый. – lesscode

ответ

1

Кажется, вы хотите что-то сделать.

case class Tag(tag:String) 

case class Thing(Tags : Seq[Tag]) 

val things :Seq[Thing] = Seq(Thing(Seq(Tag("")))) 

val q = things.map { 
    thing => new { 
    val Thing = thing 
    val Tags = thing.Tags 
    } 
}.flatMap { 
    thingAndTags => thingAndTags.Tags.map { 
    tag => new { 
     val Thing = thingAndTags.Thing 
     val Tag = tag 
    } 
    } 
}. groupBy { 
    thingAndTag => thingAndTag.Tag 
}.map { 
    tagAndSeqOfThingAndTags => 
    tagAndSeqOfThingAndTags._1 -> tagAndSeqOfThingAndTags._2.map(x => x.Thing) 
} 

Но в Scala анонимные объекты не очень распространены, но вы можете использовать Tuple2[T1,T2] вместо всех new { val ...} с,

val q = things.map { 
    thing => (thing->thing.Tags) 
}.flatMap { 
    thingAndTags => thingAndTags._2.map { 
    tag => (thingAndTags._1, tag) 
    } 
}.groupBy { 
    thingAndTag => thingAndTag._2 
}.map { 
    tagAndSeqOfThingAndTags => 
    tagAndSeqOfThingAndTags._1 -> tagAndSeqOfThingAndTags._2.map(x => x._1) 
} 

его просто немного запутанным со всеми ._1 с и ._2 s

+0

. Я в конечном итоге пошел с кортежем. Я думаю, что недостающая часть в Scala - это возможность предоставить селектор результата/элемента, но он все еще очень краток. – lesscode

+0

@lesscode, если вы действительно хотите, вы можете создать «переопределения» для методов «flatmap» и 'groupby', используя неявное преобразование из Seq в« RichSeq »(или как бы вы его называть), чтобы ваш код выглядел скорее как C# эквивалент – Danny

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