2010-05-22 17 views
21

En lenguaje como Python y Ruby para pedir la lengua qué métodos indiciarios sus soportes clase String (que nombres de los métodos contienen la palabra ‘índice’) que pueden hacerCómo obtener la lista de métodos en Scala

“”.methods.sort.grep /index/i 

Y 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; 

¿Cómo hacer la misma cosa en Scala?

+1

Creo que lo encontré "wow" .getClass.getMethods.toList.map (m => m.getName) .sort ((a, b) => (a compareTo b) <0) .filter (s = > s.matches ("index (. *)")) – skyde

+5

Por curiosidad, ¿qué vas a hacer con esos nombres de método una vez que los tienes? Si es así para que sepa qué puede escribir a continuación en una configuración interactiva, Scala REPL tiene una buena terminación de pestañas. Echale un vistazo. –

+0

¡Excelente consejo, Randall! Por alguna razón, nunca pensé en intentar ... – pdbartlett

Respuesta

39

curioso que nadie intentó una traducción más directa:

"" 
.getClass.getMethods.map(_.getName) // methods 
.sorted        // sort 
.filter(_ matches "(?i).*index.*") // grep /index/i 

Así, algunos pensamientos al azar.

  • La diferencia entre los "métodos" y los aros anteriores es llamativa, pero nunca nadie dijo que la reflexión era la fortaleza de Java.

  • Oculto algo sobre sorted anterior: en realidad toma un parámetro implícito del tipo Ordering. Si quisiera ordenar los métodos en lugar de sus nombres, tendría que proporcionarlos.

  • A grep es en realidad una combinación de filter y matches. Se ha vuelto un poco más complejo debido a la decisión de Java de hacer coincidir cadenas enteras incluso cuando ^ y $ no están especificados. Creo que tendría algún sentido tener un método de grepRegex, que tuvo Traversable como parámetros, pero ...

Por lo tanto, esto es lo que podríamos hacer al respecto:

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) 
    } 
} 

Y ahora esto es posible:

"".methods.sorted grep ("index", "i") 
+0

Eso es casi lo que tenía el OP excepto por el "ordenado" ¿Estás usando 2.8? – OscarRyz

+0

@Oscar Sí, eso es 2.8. En Scala 2.7 hay 'sort', pero no en todas las colecciones. –

+0

Esto no es realmente lo mismo - en Ruby 'x.methods' incluye métodos accesibles a través de mixins, mientras que' x.getClass.getMethods' no en Scala. Pruebe '1.methods' en Ruby y luego intente' 1.getClass.getMethods' en Scala. – Rich

4

Más o menos de la misma manera:

val names = classOf[String].getMethods.toSeq. 
    filter(_.getName.toLowerCase().indexOf(“index”) != -1). 
    map(_.getName). 
    sort(((e1, e2) => (e1 compareTo e2) < 0)) 

Pero todo en una línea.

Para que sea más fácil de leer,

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)) 
0

Sólo utilizando el código de Java directa le conseguirá la mayor parte del camino, como clases Scala siguen siendo los JVM. Sin embargo, también podría portar el código a Scala con bastante facilidad, por diversión/práctica/facilidad de uso en REPL.

1

Esto es por lo que yo tengo:

"".getClass.getMethods.map(_.getName).filter(_.indexOf("in")>=0) 

Es extraño gama Scala no tiene un método para ordenar.

edición

Se acabaría así.

"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0) 
+0

Sí, pero la lista tiene – sblundy

+0

classOf [String] .getMethods.toList.map (_. GetName) .sort (_ <_) .filter (_.matches ("index (. *)")) Esto es lo que recibí – skyde

+0

http://paste.pocoo.org/show/216854/ – missingfaktor

2

Ahora, espere un minuto.

Admito que Java es prolijo en comparación con Ruby, por ejemplo.

Pero ese fragmento de código no debería haber sido tan detallado en primer lugar.

Aquí es el equivalente:

Collection<String> mds = new TreeSet<String>(); 
    for(Method m : "".getClass().getMethods()) { 
     if(m.getName().matches(".*index.*")){ mds.add(m.getName()); } 
    } 

que tiene casi el mismo número de caracteres que el marcado como correcto, Scala versión

5

Se puede utilizar el símbolo Scala REPL. Para encontrar una lista de los métodos miembros de un objeto de cadena, por ejemplo, escriba "". y luego presione la tecla TAB (que es una cadena vacía, o incluso una que no sea emotiva, si lo desea, seguida de un punto y luego presione TAB). El REPL listará todos los métodos para miembros.

Esto se aplica también a otros tipos de variables.

+1

buena solución simple para una sesión REPL. –

+1

Esto es exactamente lo que vine a buscar aquí. Simple y elegante. – Magnus

Cuestiones relacionadas