Подтвердить что ты не робот

Как получить список методов в scala

В языке, таком как python и ruby, чтобы спросить язык, какие связанные с ним методы, поддерживаемые его строковым классом (имена методов содержат слово "index" ), вы можете сделать

"".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?

4b9b3361

Ответ 1

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

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

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

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

  • Я скрываю что-то о 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")

Ответ 2

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

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

Ответ 3

Более или менее одинаково:

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

Ответ 4

Теперь, подождите минуту.

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

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

Здесь эквивалент:

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

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

Ответ 5

Это насколько я понял:

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

Странный массив Scala не имеет метода сортировки.

изменить

Это закончилось бы так.

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

Ответ 6

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