На языке как 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?
Любопытно, что никто не пробовал более прямой перевод:
""
.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")
Насколько я понял:
"".getClass.getMethods.map(_.getName).filter( _.indexOf("in")>=0)
Странно, что массив Scala не имеет метода сортировки.
править
В итоге вроде бы.
"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0)
Простое прямое использование кода Java поможет вам в этом, поскольку классы Scala по-прежнему относятся к классам JVM. Вы также можете довольно легко перенести код на Scala для развлечения / практики / простоты использования в REPL.
Подождите минутку.
Я признаю, что Java более многословна по сравнению, например, с Ruby.
Но этот фрагмент кода изначально не должен был быть таким многословным.
Вот эквивалент:
Collection<String> mds = new TreeSet<String>();
for( Method m : "".getClass().getMethods()) {
if( m.getName().matches(".*index.*")){ mds.add( m.getName() ); }
}
В котором почти такое же количество символов, как и в версии Scala, отмеченной как правильная
Более или менее одинаково:
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))