Цикл Scala For для функции более высокого порядка

У меня есть список книг:

case class Book(name:String,authors:List[String])

val books:List[Book] = List(
                 Book(name="Code in Scala",authors=List("Viny","Vinay")),
                 Book(name="Dance in 30 days",authors=List("Namratha","Namitha")),
                 Book(name="Cook in 30 days",authors=List("Pavan")),
                 Book(name="Gym in 30 days",authors=List("Nisanth","Vinay"))
                 ) 

Теперь я хочу знать книги, в которых имя автора начинается с «Вин». Я реализовал это в цикле for, как показано ниже:

for(b<-books ; a <- b.authors ; if a.startsWith("Vin")) yield b.name

Но я не могу реализовать это с помощью функции более высокого порядка. Я пробовал, как показано ниже:

books flatMap (b=> b.authors.withFilter(a=>a.startsWith("Vin")).map(x=>x))

Это дает мне имя авторов, но я не могу получить доступ к объекту книги. Как я могу решить эту проблему? Основная цель здесь - преобразовать/перевести "циклы for" в функции более высокого порядка (flatmap/filter/map)


person Tyrion Lannister    schedule 24.11.2016    source источник
comment
Если вы удалите атрибут имени из второго примера кода, вы получите объект книги. Не могли бы вы показать свой код, попробуйте функцию более высокого порядка ??   -  person Pavel    schedule 24.11.2016


Ответы (3)


Я думаю, вы ищете перевод for-comprehension на комбинаторы (map, flatmap и filter (withFilter)).

Ты был почти там. Недостающая часть обращается к объекту книги через правую область видимости:

books.flatMap(b => b.authors.withFilter(a => a.startsWith("Vin")).map(_ => b.name))

Правила объясняются в Спецификации языка Scala (стр. 89 док, 97 pdf-)

person maasg    schedule 24.11.2016

Просто измените последний map, чтобы вернуть то, что вы хотите:

books flatMap (b => b.authors.withFilter(a => a.startsWith("Vin")).map(_ => b.name))

person lastland    schedule 24.11.2016

Я думаю, что flatMap здесь не нужен:

scala> books.filter(_.authors.exists(_.startsWith("Vin"))).map(_.name)
res4: List[String] = List(Code in Scala, Gym in 30 days)
person Paweł Bartkiewicz    schedule 24.11.2016
comment
Спасибо за ответ, но я искал, как мы можем реализовать/перевести логику цикла for только в функцию более высокого порядка (карта/плоская карта/фильтр). Это было частью курса курса. Если подумать, ваши решения также используют более высокие только функции заказа. - person Tyrion Lannister; 24.11.2016
comment
Я не думаю, что вы можете писать код, используя только функции высшего порядка. Вам всегда нужны некоторые функции первого порядка, что бы вы передали функциям более высокого порядка в противном случае? - person Paweł Bartkiewicz; 24.11.2016