Comment obtenir la liste des méthodes dans scala
Dans un langage comme python et ruby pour demander au langage quelles méthodes liées à l'index sa classe string prend en charge (quels noms de méthodes contiennent le mot "index") vous pouvez faire
“”.methods.sort.grep /index/i
Et en java
List results = new ArrayList();
Method[] methods = String.class.getMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName().toLowerCase().indexOf(“index”) != -1) {
results.add(m.getName());
}
}
String[] names = (String[]) results.toArray();
Arrays.sort(names);
return names;
Comment feriez - vous la même chose à Scala?
6 réponses
Curieux que personne n'ait essayé une traduction plus directe:
""
.getClass.getMethods.map(_.getName) // methods
.sorted // sort
.filter(_ matches "(?i).*index.*") // grep /index/i
Donc, quelques pensées aléatoires.
La différence entre les "méthodes" et les cerceaux ci-dessus est frappante, mais personne n'a jamais dit que la réflexion était la force de Java.
Je cache quelque chose à propos de
sorted
ci-dessus: il prend en fait un paramètre implicite de typeOrdering
. Si je voulais trier les méthodes elles-mêmes au lieu de leurs noms, je devrais le fournir.Un
grep
est en fait une combinaison defilter
etmatches
. Il est rendu un peu plus complexe en raison de la décision de Java de faire correspondre des chaînes entières même lorsque^
et$
ne sont pas spécifiés. Je pense qu'il serait logique d'avoir une méthodegrep
surRegex
, qui a pris {[12] } comme paramètres, mais...
Donc, voici ce que nous pourrions faire à ce sujet:
implicit def toMethods(obj: AnyRef) = new {
def methods = obj.getClass.getMethods.map(_.getName)
}
implicit def toGrep[T <% Traversable[String]](coll: T) = new {
def grep(pattern: String) = coll filter (pattern.r.findFirstIn(_) != None)
def grep(pattern: String, flags: String) = {
val regex = ("(?"+flags+")"+pattern).r
coll filter (regex.findFirstIn(_) != None)
}
}
Et maintenant, c'est possible:
"".methods.sorted grep ("index", "i")
Vous pouvez utiliser l'invite Scala REPL. Pour trouver la liste des méthodes membres d'un objet string, par exemple, tapez "". et puis appuyez sur la touche TAB (c'est une chaîne vide - ou même une chaîne non vide, si vous le souhaitez, suivie d'un point, puis appuyez sur TAB). Le REPL listera pour vous toutes les méthodes membres.
Cela s'applique également aux autres types de variables.
Plus ou moins de la même manière:
val names = classOf[String].getMethods.toSeq.
filter(_.getName.toLowerCase().indexOf(“index”) != -1).
map(_.getName).
sort(((e1, e2) => (e1 compareTo e2) < 0))
Mais tous sur une seule ligne.
Pour le rendre plus lisible,
val names = for(val method <- classOf[String].getMethods.toSeq
if(method.getName.toLowerCase().indexOf("index") != -1))
yield { method.getName }
val sorted = names.sort(((e1, e2) => (e1 compareTo e2) < 0))
Maintenant, attendez une minute.
Je concède que Java est verbeux par rapport à Ruby par exemple.
Mais ce morceau de code n'aurait pas dû être aussi verbeux en premier lieu.
Voici l'équivalent :
Collection<String> mds = new TreeSet<String>();
for( Method m : "".getClass().getMethods()) {
if( m.getName().matches(".*index.*")){ mds.add( m.getName() ); }
}
Qui a presque le même nombre de caractères que la version Scala marquée comme correcte
C'est aussi loin que je suis:
"".getClass.getMethods.map(_.getName).filter( _.indexOf("in")>=0)
C'est étrange que le tableau Scala n'ait pas de méthode de tri.
Modifier
Ça finirait comme.
"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0)
Simplement en utilisant le code Java direct vous obtiendrez la plupart du chemin, car les classes Scala sont toujours celles de la JVM. Vous pouvez également porter le code sur Scala assez facilement, pour le plaisir / la pratique/la facilité d'utilisation dans REPL.