|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|

[文字列処言語間理比較表]の変更点

    

「文字列処言語間理比較表」の編集履歴(バックアップ)一覧はこちら

文字列処言語間理比較表」の最新版変更点

追加された行はこの色になります。

削除された行はこの色になります。

 ここ→<a href=
-"http://0xcc.net/blog/archives/000137.html">配列操作の比較表</a><a href="http://0xcc.net/blog/archives/000137.html">に</a>触発されて、Rubyの文字列メソッドの対応物をJavaとHaskellで探してみました。<br>
+"http://0xcc.net/blog/archives/000137.html">配列操作の比較表</a>に触発されて、Rubyの文字列メソッドの対応物をJavaとHaskellで探してみました。<br>
 
 <br>
 Javaの文字列処理がそれほど高機能じゃないのはある程度想定内だったけど、Haskellもなかなか1対1の対応物がない。<br>
 
 lines,unlinesとか逆にあまったけど。<br>
 <br>
 そもそもHaskellのソレって文字列処理用っていうよりほとんど汎用リスト操作関数なわけで。<br>
 
 <br>
 Haskellって<br>
 「汎用性の高い関数を用意したから自由に組み合わせて使ってね」<br>
 
 って思想だと思うわけで。<br>
 カリー化された関数の強力な応用力とあいまってこれはこれで一つの便利さの方向性だとはおもう。<br>
 
 <br>
 ただこれの欠点は<br>
 「もっとエレガントで短い書き方があるんじゃないか?」<br>
 
 って不安がいつまでも付きまとう事。<br>
 (しかもタチの悪い事にパズルみたいで楽しすぎる!)<br>
 自分の修行が足りなくてイディオムを知らないせいもあるけどね。<br>
 
 (これ調べてるうちに、<a href=
 "http://www3.atwiki.jp/nanakoso/pages/4.html">HaskellでLha</a>にもいろいろ直したいところが!)<br>
 
 <br>
 <br>
 Javaのパッケージ名やHaskellのモジュール名を明示するため、必要なものは完全名で書きました。<br>
 
 (実際ほとんどの場合ソースの頭でimport文を使って短くかけるようにします。)<br>
 
 <br>
 <br>
 <table style="width: 485px; height: 3076px;" border="1">
 <tbody>
 <tr>
 <th>Ruby (String)</th>
 <th>Java</th>
 <th>Haskell</th>
 </tr>
 <tr>
 <td>s = "abc"</td>
 <td>String s = "abc"</td>
 <td>s = "abc"</td>
 </tr>
 <tr>
 <td>s = x + y</td>
 <td>s = x + y</td>
 <td>s = x ++ y</td>
 </tr>
 <tr>
 <td>s == x</td>
 <td>s.equals(x)<br></td>
 <td>s == x<br></td>
 </tr>
 <tr>
 <td>s % [x, y]<br>
 sprintf(s, x, y)<br></td>
 <td>String.format(s, x, y)//J2SE5.0より<br></td>
 <td>Text.Printf.printf s x y</td>
 </tr>
 <tr>
 <td>[x, y, z].join(s)</td>
 <td><br></td>
 <td>foldr1 (¥a b-&gt;a ++ s ++ b) [x,y,z]<br></td>
 </tr>
 <tr>
 <td>s.capitalize</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.capitalize!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td style="vertical-align: top;"><code>s.casecmp(x)</code></td>
 <td style="vertical-align: top;">// s.equalsIgnoreCase(x)<br>
 // ってのがあるけど同値判定だけだし、、<br></td>
 <td style="vertical-align: top;"><br></td>
 </tr>
 <tr>
 <td>s.center(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.chomp</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.chomp!</td>
 <td><br>
 <br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.chop</td>
 <td><br></td>
 <td>init s<br></td>
 </tr>
 <tr>
 <td>s.chop!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.clear</td>
 <td>// sbはStringBuffer型<br>
 sb.setLength(0);<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.concat(x)</td>
 <td>// sbはStringBuffer型<br>
 sb.append(x);<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.count(x)</td>
 <td><br></td>
 <td><br>
 length filter (flip elem x) s</td>
 </tr>
 <tr>
 <td>s.crypt(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.delete(x)</td>
 <td><br></td>
 <td><br>
 filter (flip notElem x) s</td>
 </tr>
 <tr>
 <td>s.delete!(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.downcase</td>
 <td>s.toLowerCase()<br></td>
 <td>map Data.Char.toLower s<br></td>
 </tr>
 <tr>
 <td>s.downcase!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td rowspan="2">s.each_byte {|x|<br>
 ... }</td>
 <td>for(int i=0; i &lt; s.length(); i++){<br>
 char x = s.charAt(i);<br>
 ...<br>
 }<br></td>
 <td rowspan="2">mapM_ (¥x-&gt;...) s<br>
 --<br>
 副作用を含む処理を順次起動するって意味では<br>
 mapM_で正解だけど、...のところはモナドじゃないといけない。<br>
 
 実際そこまでは要らなくて集計値とか計算結果のリストが欲しいだけで<br>
 
 foldシリーズやただのmapで十分ってことも多いと思われる。<br>
 
 <a name="a1" title="a1" id="a1"></a><br></td>
 </tr>
 <tr>
 <td>//J2SE5.0より<br>
 for(char x:s.toCharArray()){<br>
 ...<br>
 }</td>
 </tr>
 <tr>
 <td rowspan="2">s.each_line {|x|<br>
 ... }</td>
 <td>String[] xs = s.split("¥n",-1);<br>
 for(int i=0 ; i &lt; xs.length; i++){<br>
 String x = xs[i];<br>
 ...<br>
 }<br></td>
 <td rowspan="2">mapM_ (¥x-&gt;...) $ lines s</td>
 </tr>
 <tr>
 <td>//J2SE5.0より<br>
 for(String x:s.split("¥n",-1)){<br>
 ...<br>
 }</td>
 </tr>
 <tr>
 <td>s.empty?</td>
 <td>s.length() == 0<br></td>
 <td>null s<br></td>
 </tr>
 <tr>
 <td>s.end_with?(x)</td>
 <td>s.endsWith(x)<br></td>
 <td>Data.List.isSuffixOf x s<br></td>
 </tr>
 <tr>
 <td>s.gsub(x, y)</td>
 <td>s.replaceAll(x, y)<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.gsub!(x, y)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.hex<br>
 s.to_i(16)<br></td>
 <td><br>
 Integer.parseInt(s,16)</td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.include?(x)</td>
 <td>s.indexOf(x) &gt;= 0<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.index(x)</td>
 <td>s.indexOf(x)</td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.insert(i, x)</td>
 <td>// sbはStringBuffer型<br>
 sb.insert(i,x);<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.length<br>
 s.size<br></td>
 <td>s.length()<br></td>
 <td>length s<br></td>
 </tr>
 <tr>
 <td>s.ljust(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.lstrip</td>
 <td><br></td>
 <td>dropWhile Data.Char.isSpace s<br></td>
 </tr>
 <tr>
 <td>s.lstrip!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.match(x)</td>
 <td>s.matches(x)<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>x.match(s)</td>
 <td>java.util.regex.Pattern.matches(x, s)<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.next<br>
 s.succ</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.next!<br>
 s.succ!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.oct<br>
 s.to_i(8)<br></td>
 <td>Integer.parseInt(s,8)</td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.partition(x)</td>
 <td><br></td>
 <td>Data.List.partition x s<br></td>
 </tr>
 <tr>
 <td>s.replace(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.reverse</td>
 <td><br></td>
 <td>reverse s<br></td>
 </tr>
 <tr>
 <td>s.reverse!</td>
 <td>// sbはStringBuffer型<br>
 sb.reverse();</td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.rindex(x)</td>
 <td>s.lastIndexOf(x)<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.rjust(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.rpartition(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.rstrip</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.rstrip!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.scan(x) { ... }</td>
 <td>TODO<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s[i]<br>
 s.slice(i)<br></td>
 <td>s.charAt(i)<br></td>
 <td>s !! i<br></td>
 </tr>
 <tr>
 <td>s[i..-1]<br>
 s.slice(i..-1)<br></td>
 <td>s.substring(i)<br></td>
 <td>drop i s<br></td>
 </tr>
 <tr>
 <td>s[i, l]<br>
 s.slice(i, l)<br></td>
 <td>s.substring(i,i+l)</td>
 <td>take l $ drop i s<br></td>
 </tr>
 <tr>
 <td>s[i..j]<br>
 s.slice(i..j)<br></td>
 <td>s.substring(i,j+1)<br></td>
 <td>take (l-i+1) $ drop i s</td>
 </tr>
 <tr>
 <td>s[i...j]<br>
 s.slice(i...j)<br></td>
 <td>s.substring(i,j)</td>
 <td>take (l-i) $ drop i s</td>
 </tr>
 <tr>
 <td>s.split(x)</td>
 <td>s.split(x)<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.start_with?(x)*4</td>
 <td>s.startsWith(x)<br></td>
 <td>Data.List.isPrefixOf x s</td>
 </tr>
 <tr>
 <td>s.strip</td>
 <td>s.trim()<br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.strip!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.sub(x, y)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.sub!(x, y)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.swapcase</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.to_f</td>
 <td>Float.parseFloat(s)<br></td>
 <td>read s<br>
 --この式が使用される場所の型によって適宜、変換関数の実装が(コンパイル時に)選択される(多相型)<br>
 </td>
 </tr>
 <tr>
 <td>s.to_i</td>
 <td>Integer.parseInt(s)<br></td>
 <td>read s<br>
 --同上<br></td>
 </tr>
 <tr>
 <td>s.tr!(x, y)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.tr_s!(x, y)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.unpack(x)</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>s.upcase</td>
 <td>s.toUpperCase()<br></td>
 <td>map Data.Char.toUpper s<br></td>
 </tr>
 <tr>
 <td>s.upcase!</td>
 <td><br></td>
 <td><br></td>
 </tr>
 <tr>
 <td>Regexp.escape(s)<br>
 Regexp.quote(s)<br></td>
 <td><br></td>
 <td><br></td>
 </tr>
 </tbody>
 </table>
 <span id="a1"></span><br>