2010-05-22 33 views
21

在像Python和Ruby語言問什麼指數相關的方法的字符串類支持(該方法的名字包含單詞‘索引’),你可以做的語言如何獲得方法列表中階

「」.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; 

你將如何在斯卡拉做同樣的事情?

+1

想我發現它 「哇」.getClass.getMethods.toList.map(m => m.getName).sort((a,b)=>(a比較b)<0).filter(s = > s.matches(「index(。*)」)) – skyde 2010-05-22 01:08:42

+5

出於好奇,一旦你有了這些方法名稱,你會怎麼做?如果是這樣,你知道你可以在交互式設置中輸入下一個內容,Scala REPL具有良好的Tab完成功能。一探究竟。 – 2010-05-22 01:41:46

+0

優秀的提示,Randall!出於某種原因,我只是從來沒有想過嘗試... – pdbartlett 2010-05-22 02:10:57

回答

39

奇怪的是,沒有人嘗試過更直接的翻譯:

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

所以,一些雜感。

  • 「方法」和上面的箍環之間的區別是驚人的,但沒有人說反射是Java的強項。

  • 我在上面隱藏了一些關於sorted的東西:它實際上需要一個類型爲Ordering的隱式參數。如果我想將方法​​本身而不是他們的名字排序,我必須提供它。

  • A grep實際上是filtermatches的組合。由於Java決定匹配整個字符串,即使沒有指定^$,情況也會變得更加複雜。我認爲這某種意義上對Regex一個grep方法,歷時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 2010-05-22 02:17:49

+0

@Oscar是的,那是2.8。在Scala 2.7上有'sort',但不是所有的集合。 – 2010-05-22 02:31:10

+0

這不完全相同 - 在Ruby中'x.methods'包含可通過mixins訪問的方法,而'x.getClass.getMethods'不包含在Scala中。在Ruby中嘗試'1.methods',然後在Scala中嘗試'1.getClass.getMethods'。 – Rich 2014-01-20 18:02:29

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) 

很奇怪斯卡拉陣列沒有排序方法。

編輯

它最終會像。

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

是的,但列表確實是 – sblundy 2010-05-22 01:19:17

+0

classOf [String] .getMethods.toList.map(_。getName).sort(_ <_).filter(_.matches(「index(。*)」)) 這就是我得到 – skyde 2010-05-22 01:21:29

+0

http://paste.pocoo.org/show/216854/ – missingfaktor 2010-05-22 01:23:12

2

現在,等一下。

我承認Java比較冗長,比如Ruby。

但是這段代碼本來不應該如此冗長。

下面是等價的:

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

這幾乎相同數量的字符作爲標記爲正確,斯卡拉版本

5

您可以使用Scala的REPL提示。要查找列表字符串對象的成員方法,例如,鍵入「」。然後按TAB鍵(這是一個空字符串 - 如果你喜歡,也可以是非空字符串,後面跟着一個點,然後按Tab鍵)。 REPL會爲您列出所有成員方法。

這也適用於其他變量類型。

+1

REPL會話的簡單解決方案。 – 2016-01-24 22:00:12

+1

這正是我來這裏尋找的。簡單而優雅。 – Magnus 2016-05-03 10:08:37