2016-10-21 3 views
0

Тип подписи groupBy есть (на языке Scala, но на самом деле зависит от языка):Есть ли термин для groupBy, который возвращает несколько групп?

def groupBy[K](f: A => K): Map[K, Seq[A]] 

Я реализовал groupBy что возвращает несколько K, так что каждый A можно поместить в несколько групп одновременно. Что-то вроде этого:

def multiGroupBy[K](f: A => Seq[K]): Map[K, Seq[A]] 

я сделать что-то вроде:

case class Animal(name: String, traits: Seq[String]) 

List(
    Animal("cat", Seq("nocturnal", "feline")), 
    Animal("dog", Seq("canine")), 
    Animal("wolf", Seq("nocturnal", "canine")) 
).multiGroupBy(animal => animal.traits) 

// Map(nocturnal -> List(cat, wolf), feline -> List(cat), canine -> List(dog, wolf)) 

Название multiGroupBy работает, но мне интересно, если есть уже термин для работы, как и выше (возможно в Haskell мире?).

+0

ли ваш проект имеет функциональное программирование библиотеки зависимостей, таких как '' Scalaz' или cats'? Если нет, не возражаете ли вы добавить его? Потому что это можно решить с помощью «Monoid» и «foldMap». –

+0

@MustafaSimav Да, мой проект зависит от 'Scalaz'! –

+0

Не следует ли 'multiGroupBy' возвращать' Map [K, Seq [A]] ', а не' Map [K, A] '? –

ответ

1

Если у вас есть Scalaz зависимости, вы можете сделать это с помощью foldMap.

import scalaz._ 
import Scalaz._ 

case class Animal(name: String, traits: Seq[String]) 

val animals = List(
    Animal("cat", Seq("nocturnal", "feline")), 
    Animal("dog", Seq("canine")), 
    Animal("wolf", Seq("nocturnal", "canine")) 
) 

val r1 = animals.foldMap(a => a.traits.map(t => t -> List(a)).toMap) 
println(r1) 
// Map(nocturnal -> List(Animal(cat,List(nocturnal, feline)), Animal(wolf,List(nocturnal, canine))), feline -> List(Animal(cat,List(nocturnal, feline))), canine -> List(Animal(dog,List(canine)), Animal(wolf,List(nocturnal, canine)))) 

val r2 = animals.foldMap(a => a.traits.map(t => t -> List(a.name)).toMap) 
println(r2) 
// Map(nocturnal -> List(cat, wolf), feline -> List(cat), canine -> List(dog, wolf)) 

То, что мы сделали здесь в том, что мы создали Map[String, List[Animal]] для каждого животного в списке животных, и пусть Monoid[Map[String, List[Animal]]] сливаться друг карты.

Например, Animal("cat", Seq("nocturnal", "feline")) было использовано Map("nocturnal" -> List(Animal("cat", Seq("nocturnal", "feline"))), "feline" -> List(Animal("cat", Seq("nocturnal", "feline")))).

Для furhter чтения о моноиде: http://eed3si9n.com/learning-scalaz/Monoid.html

+0

Спасибо за ваш ответ. Но я хотел знать, что это не реализация такой операции (я реализовал ее уже с использованием аналогичной реализации, как scala 'groupBy'), но уже существует метод для такой операции. Я уверен, что в scala std нет эквивалента, но мне было любопытно, есть ли общая терминология для него в общем сообществе функционального программирования. –

+0

Так что я могу назвать свой новый метод лучше, чем 'multiGroupBy';) –

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