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?

23
demandé sur James McMahon 2010-05-22 04:37:56

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 type Ordering. 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 de filter et matches. 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éthode grep sur Regex, 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")
42
répondu Daniel C. Sobral 2010-05-22 02:29:19

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.

6
répondu Saichovsky 2018-06-07 11:24:14

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))
4
répondu sblundy 2010-05-22 01:36:50

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

2
répondu OscarRyz 2010-05-22 03:20:05

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)
1
répondu OscarRyz 2010-05-22 01:42:37

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.

0
répondu pdbartlett 2010-05-22 00:55:08