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

На языке как Python и рубин для выяснения у языка, что связанные с индексом методы его поддержки строкового класса (какие названия методов содержат слово “индекс”) можно сделать

“”.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?

28
задан James McMahon 15 July 2012 в 19:46
поделиться

5 ответов

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

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

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

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

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

  • grep на самом деле представляет собой комбинацию фильтра и совпадений . Это немного усложнилось из-за решения 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")
44
ответ дан 28 November 2019 в 02:51
поделиться

Насколько я понял:

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

Странно, что массив Scala не имеет метода сортировки.

править

В итоге вроде бы.

"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0)
2
ответ дан 28 November 2019 в 02:51
поделиться

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

1
ответ дан 28 November 2019 в 02:51
поделиться

Подождите минутку.

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

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

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

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

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

3
ответ дан 28 November 2019 в 02:51
поделиться

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

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))
5
ответ дан 28 November 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: