2010-05-22 4 views
21

В языке, как питон и рубиновая задать язык, что индекс связанных методов его строку класс поддерживает (имена которых методы содержат слово „индекс“) вы можете сделатьКак получить список методов в Скале

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

И в 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; 

Как бы вы сделать то же самое в Scala?

+1

Думаю, что я нашел его «wow» .getClass.getMethods.toList.map (m => m.getName) .sort ((a, b) => (a compareTo b) <0) .filter (s = > s.matches ("index (. *)")) – skyde

+5

Из любопытства, что вы собираетесь делать с этими именами методов, как только вы их получите? Если это так, вы знаете, что вы можете ввести далее в интерактивной настройке, Scala REPL имеет хорошее завершение табуляции. Проверьте это. –

+0

Отличный совет, Рэндалл! По какой-то причине я просто не думал попробовать ... – pdbartlett

ответ

39

Любопытно, что никто не пытался более прямой перевод:

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

Так, некоторые случайные мысли.

  • Разница между «методами» и обручами выше поразительна, но никто никогда не говорил, что отражение было силой Явы.

  • Я скрываю что-то около sorted выше: он фактически принимает неявный параметр типа Ordering. Если бы я хотел сортировать сами методы, а не их имена, я должен был бы предоставить их.

  • A grep на самом деле представляет собой комбинацию из filter и matches. Это немного сложнее из-за решения Java согласовать целые строки, даже если ^ и $ не указаны. Я думаю, что это какой-то смысл иметь grep метод на Regex, который принял Traversable в качестве параметров, но ...

Итак, вот что мы можем сделать по этому поводу:

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

И теперь это возможно:

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

Это почти то, что было у OP, кроме «отсортированного». А вы используете 2.8? – OscarRyz

+0

@ Оскар Да, это 2.8. На Scala 2.7 существует 'sort', но не во всех коллекциях. –

+0

Это не совсем то же самое - в Ruby 'x.methods' включены методы, доступные через mixins, тогда как' x.getClass.getMethods' не находится в Scala. Попробуйте '1.methods' в Ruby, а затем попробуйте' 1.getClass.getMethods' в Scala. – Rich

4

Более или менее точно так же:

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

Но все в одной строке.

Чтобы сделать его более удобным для чтения,

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

Просто с помощью кода Java прямой получит вам большую часть пути там, как классы Scala еще JVM из них. Вы также можете легко переносить код на Scala, но для удовольствия/практики/простоты использования в REPL.

1

Это, насколько я получил:

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

Это странно массив Scala не метод сортировки.

редактировать

Это будет в конечном итоге, как.

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

Да, но список – sblundy

+0

classOf [String] .getMethods.toList.map (_. GetName) .sort (_ <_) .filter (_.matches ("index (. *)")) Это то, что я получил – skyde

+0

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

2

Теперь подождите.

Я признаю, что Java является многословием по сравнению с Ruby, например.

Но этот фрагмент кода не должен был быть таким подробным на первом месте.

Вот эквивалент:

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

Который имеет почти такое же количество символов, как помеченный как правильно, Scala версии

5

Вы можете использовать Scala REPL подсказку. Чтобы найти список методов-членов строкового объекта, например, введите «». и затем нажмите клавишу TAB (это пустая строка - или даже несимвольная, если хотите, затем нажмите точку, а затем нажмите TAB). REPL перечислит для вас все методы участников.

Это относится и к другим типам переменных.

+1

хорошее простое решение для сеанса REPL. –

+1

Именно это я и искал. Простой и элегантный. – Magnus

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