Как получить список методов в 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?
Ответы
Ответ 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.