Example10.2

10.2 For 内包表記によるクエリ

       (Querying with For-Comprehensions)

for 内包表記は、データベースのクエリ言語による一般的操作と本質的に同じです。たとえば、データベース books があり、本のリストとして表現されているとしましょう。ただし Book は次のように定義されるものとします。

case class Book(title: String, authors: List[String]) 

次はデータベースの小さなサンプルです。

val books: List[Book] = List( 
  Book("Structure and Interpretation of Computer Programs", 
    List("Abelson, Harold", "Sussman, Gerald J.")), 
  Book("Principles of Compiler Design", 
    List("Aho, Alfred", "Ullman, Jeffrey")), 
  Book("Programming in Modula-2", 
    List("Wirth, Niklaus")), 
  Book("Introduction to Functional Programming"), 
    List("Bird, Richard")), 
  Book("The Java Language Specification", 
    List("Gosling, James", "Joy, Bill", "Steele, Guy", "Bracha, Gilad")))

このとき、著者の姓が "Ullman" である本すべての書名を探すには、

for (b <- books; a <- b.authors if a startsWith "Ullman") 
yield b.title 

(ここで startsWith は java.lang.String のメソッド)。あるいは書名が "Program" で始まる本の書名を探すには

for (b <- books if (b.title indexOf "Program") >= 0) 
yield b.title 

あるいは、少なくとも二冊の本を書いたすべての著者の名前をデータベース上で探すには、

for (b1 <- books; b2 <- books if b1 != b2; 
      a1 <- b1.authors; a2 <- b2.authors if a1 == a2) 
yield a1

最後のコードはまだ完全ではありません。なぜなら著者が結果リストに複数回現れるからです。結果リストから重複した著者を除く必要があります。これは次の関数を使えばできます。

def removeDuplicates[A](xs: List[A]): List[A] = 
  if (xs.isEmpty) xs 
  else xs.head :: removeDuplicates(xs.tail filter (x => x != xs.head)) 

メソッド removeDuplicates の最後の式は for 内包表記を使って、等価に次のように表現できます。

xs.head :: removeDuplicates(for (x <- xs.tail if x != xs.head) yield x) 

名前:
コメント:

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2011年02月24日 08:49
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。