0
votes

Comment trier un Iterable sans créer de Seq intermédiaire?

J'ai une carte de String -> Foo et je veux obtenir une collection triée de Foos par Foo.priority:

fooMap.collect { case (k, f) if k.startWith("F") => f }.to[Seq](orderedCanBuildFrom) //does not work

Comment puis-je éviter le intermédiaire toSeq ? Puis-je créer une nouvelle collection et l'insérer à la commande? Peut-être quelque chose comme:

fooMap.collect { case (k, f) if k.startWith("F") => f }.toSeq.sortBy(_.priority)


5 commentaires

Pouvez-vous expliquer pourquoi vous voulez faire cela? Quel est le problème avec la conversion vers un type de collection approprié avant le tri?


@Tim Problèmes de performance. Nous avons une très grande collection à trier, une allocation de mémoire et une latence très strictes.


Quel est le type de priorité ? Entier?


@ KrzysztofAtłasik Ya c'est un Int


@texasbruce Peut-il prendre n'importe quelle valeur ou seulement l'ensemble limité (comme [1,2,3..100])? Peut-être que vous devriez aller pour le tri de comptage?


3 Réponses :


4
votes

Vous ne pouvez pas trier directement un ibler directement, et le tri d'insertion que vous décrivez sera très lent pour les grandes collections.

La meilleure option est probablement à convertir en tableau et à utiliser le SCALA.UTIL.SORTING Paquet qui fournit un tri en place de Array s.


0 commentaires

1
votes

Puisque vous dites que vous êtes à court de mémoire et de latence, essayez ceci

fooMap.view.filter(_._1.startsWith("F")).map(_._2).toSeq.sortBy(_.priority)

Sinon, envisagez d'acheter plus de mémoire et / ou de vitesse :).


0 commentaires

1
votes

Pour Scala 2.12 et inférieur, j'utilise un CanBuildFrom personnalisé pour permettre à map / collect de se transformer en un type de collection différent. scala.collection.breakOut fait cela automatiquement:

import scala.collection.breakOut

fooMap.collect[Foo, Seq[Foo]]  { 
  case (k, f) if k.startWith("F") => f
}(breakOut).sortBy(_.priority)

Pour Scala 2.13 et supérieur, depuis CanBuildFrom et breakOut code > n'est plus disponible et les vues sont plus fiables, j'utiliserais une vue comme indiqué dans la réponse de @ volty-de-qua, puisque ce n'est qu'à partir de la version 2.13 que collection. considérablement simplifié et devrait désormais fonctionner de manière fiable.


0 commentaires