オブジェクト

  • JavaScript のオブジェクトは Ruby でいうクラス
  • インスタンスの生成
today = new Data();      // new コンストラクタ;
  • メソッド呼び出し
today.getDay();      // インスタンス名.メソッド名();
  • インスタンスメソッドとクラスメソッドがある。
  • インスタンス名.プロパティ名 でプロパティ参照
  • インスタンス名.プロパティ名 = 値; でプロパティを設定
  • 同じインスタンスに続けてアクセスするには with 文
with(document) {
    write("<h1>Hello!</h1>");
    write("This is JavaScript.");
}

変数

  • 宣言しなくても使えるけど,明示的に宣言するには:
var v1;
var v2, v3, v4;
var v5 = 10;      // 同時に初期化
  • 数値型,文字列型,ブーリアン型,オブジェクト型 etc.
  • リファレンス型とプリミティブ型
  • 変数名は,アルファベットか _ で始まり,2文字目以降には数字も使える。
  • 予約語は使えない。

予約語

break else new var
case finally return void
chatch for switch while
continue function this with
default if throw
delete in try
do instanceof tpeof

将来のために予約されている語もある:

abstract enum int short
boolean export interface static
bye extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public

演算子

当たり前のものは省略。

  • インクリメント(++)/デクリメント(–)。前置と後置。
  • 論理演算子: !/&&/||。not/and/or はない。
  • ビット演算子: &(論理積)/|(論理和)/^(排他的論理和)
  • シフト演算子: <<(左シフト)/>>(右算術シフト)/>>>(右論理シフト)。右算術シフトは,符号ビットは保存されるようにシフトされる。
var x = 10;
x >> 1;       // -5
x >>> 1;      // 2147483643
  • typeof演算子:値の型を調べる。

’===’ と ’==’

  • ‘===’ は型も含めて同一でなければ true にならない。
  • ‘==’ は型が違っても構わない。たとえば,数値の 10 と文字列の “10” が true になる。
var n = 10;
var s = "10";

with(document) {
    write("n = ", n, " ; type: ", typeof n, "<br>");
    write("s = ", s, " ; type: ", typeof s, "<br>");
    write("n === s : ", n === s, "<br>");      // false
    write("n == s : ", n == s, "<br>");        // true
}

故あって JavaScript に手を出す

基本事項。

  • 大文字と小文字を区別
  • ステートメントの終わりにはセミコロン;
  • // 行末までコメント
  • /* 複数行のコメント */
  • スクリプトは script タグで囲む。
  • JavaScript を認識できないブラウザのために,<!– と //–> で囲む(HTMLのコメント扱い)。
<script language="javascript" type="text/javascript">
<!--
    document.write("<hr>");
     document.write("<h1>This is JavaScirpt.<h1>");
     document.write("<hr>");
//-->
</script>
  • 関数の定義などは head エレメント内,出力などはその場所に書くのが一般的。
  • 外部ファイルにしたスクリプトは script エレメントの src 属性で指定する。
<script type="text/javascript" src="ext.js"></script>

文字列を空白で区切る

テキストファイルから入力を受け付ける時にはよく使う。あとはカンマ区切りなんかも。

import Data.Char

splitBy :: (a -> Bool) -> [a] -> [[a]]
splitBy p [] = []
splitBy p xs = a : (splitBy p $ dropWhile p $ b)
  where
    (a, b) = break p xs

splitBySpace :: String -> [String]
splitBySpace = splitBy isSpace
*Main> splitBySpace "a b c"
["a","b","c"]
*Main> splitBySpace " a b c "
["","a","b","c"]

正規表現(Text.Regex)を使えばもっとシンプルに書ける。

import Text.Regex

splitBySpace' :: String -> [String]
splitBySpace' = splitRegex (mkRegex " +")
*Main> splitBySpace' "a b c"
["a","b","c"]
*Main> splitBySpace' " a b c "
["","a","b","c",""]

……けど,ちょっと動作が違うな。
ちなみに Ruby の String#split は上の splitBySpace と同じ動作。

D:\>irb --simple-prompt
>> "a b c".split(/ +/)
=> ["a", "b", "c"]
>> " a b c ".split(/ +/)
=> ["", "a", "b", "c"]

リストによる正方行列(つづき)

cf. 今日の一行 – リストによる正方行列処理

週をまたいでしまった。解答例もでてるけど。

問題3。これも内包表記で。

boxing :: [[a]] -> [[a]]
boxing m = [[m!!x!!y| x <- [0..l1], y <- [0..l1], x`div`l2 == i, y`div`l2 == j] | i <- [0..l3], j <- [0..l3]]
  where
    l1 = length m - 1
    l2 = (floor . sqrt . fromIntegral . length) m
    l3 = l2 -1

行列のサイズから n を求めるとこで型が合わずにはまった(sqrt(Floating a) => a -> a,必要なのは Int)。結局 floor を使った。

パターンの回転

パソコン甲子園というのを見つけた。
プログラミング部門の問題が公開されてるので(↓)ちょっとやってみよう。

正方行列つながりってことで問題01。

8文字×8行のパターンを右回りに90度、180度、270度回転させて出力し終了するプログラムを作成してください。

rotateMatrixR で右に90度回転させる。左に回転させる rotateMatrixL があるのは,勘違いしてさきに書いちゃったから。でも考えると右回転はちょっと面倒そうだな。これで正解かも。
main は手抜き。美しくない。

module Main (main) where

main :: IO ()
main = do cs <- getContents >>= return . lines
          putStrLn "90"
          showMatrix $ rotateMatrixR cs
          putStrLn "180"
          showMatrix $ rotateMatrixR $ rotateMatrixR cs
          putStrLn "270"
          showMatrix $ rotateMatrixR $ rotateMatrixR $ rotateMatrixR cs

rotateMatrixL :: [[a]] -> [[a]]
rotateMatrixL [xs] = [[x]| x <- reverse xs]
rotateMatrixL (xs:xss) = zipWith (:) (reverse xs) (rotateMatrixL xss)

rotateMatrixR :: [[a]] -> [[a]]
rotateMatrixR = reverse . rotateMatrixL . reverse

showMatrix :: [String] -> IO ()
showMatrix = putStr . unlines

実行例。

D:\>type input01.txt
#*******
#*******
#*******
#*******
#*******
#*******
#*******
########
D:\>runhaskell problem01.hs < input01.txt
90
########
#*******
#*******
#*******
#*******
#*******
#*******
#*******
180
########
*******#
*******#
*******#
*******#
*******#
*******#
*******#
270
*******#
*******#
*******#
*******#
*******#
*******#
*******#
########

追記:
右回転の方が簡単だった……orz

rotateMatrixR' :: [[a]] -> [[a]]
rotateMatrixR' = transpose . reverse
*Main> showMatrix sampleMatrix
#*******
#*******
#*******
#*******
#*******
#*******
#*******
########
*Main> showMatrix $ rotateMatrixR' sampleMatrix
########
#*******
#*******
#*******
#*******
#*******
#*******
#*******
*Main> showMatrix $ rotateMatrixR' $ rotateMatrixR' sampleMatrix
########
*******#
*******#
*******#
*******#
*******#
*******#
*******#

さらに追記:
ちがう!左回転も同じくらい簡単だ。

rotateMatrixL' :: [[a]] -> [[a]]
rotateMatrixL' = reverse . transpose