scala筑基篇-01-List操作


  • List概要
  • 特性
  • 作成リスト
  • 操作
  • listの基本操作
  • listクラスの1次メソッド
  • 接続
  • 長さ
  • reverse
  • apply indices
  • zip
  • mkString

  • listクラスの高次メソッド
  • foreach
  • map
  • flatMap
  • filter
  • partition
  • find
  • takeWhile dropWhile span
  • 論断forallexists
  • 折りたたみ
  • ソート
  • listオブジェクトのメソッド

  • List概要
    とくせい
  • 可変
  • 再帰構造
  • 同構造(同質)の:元素のタイプは一致しなければならない
  • コヒーレント:SがTのサブタイプである場合、List[S]はList[T]のサブタイプであり、javaの汎用
  • とは異なる.
  • 空リストはList[Nothing]、Nil
  • リストの作成
  • のすべてのListは、空リストNilとオペレータ::とによって構成する、::は、フロントエンドからの拡張リストを示す.
  • 実際には、リスト(e 1,e 2,...)のような形で作成するリストは、下位層でもNilおよび::を用いて構築された
  • である.
    scala> List(1,2,3)
    res0: List[Int] = List(1, 2, 3)
    
    scala> 1::Nil
    res1: List[Int] = List(1)
    
    scala> 2::res1
    res2: List[Int] = List(2, 1)
    
    scala> 3::res2
    res3: List[Int] = List(3, 2, 1)

    操作
    Listの基本操作
    method
    DESC
    head
    Listの最初の要素
    tail
    head以外の要素からなるリスト
    isEmpty
    Listが空か
    last
    Listの最後の要素
    init
    last以外の要素からなるリスト
    scala> val l1=List(1,2,3,4,5)
    l1: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> l1.tail
    res4: List[Int] = List(2, 3, 4, 5)
    
    scala> l1.head
    res5: Int = 1
    
    scala> l1.isEmpty
    res6: Boolean = false
    
    scala> l1.init
    res7: List[Int] = List(1, 2, 3, 4)
    
    scala> l1.last
    res8: Int = 5

    Listクラスの1次メソッド
    せつぞく
    リストのリンクオペレータ:::は、拡張要素オペレータ::と同様に右結合されている.すなわち、xs:::ys:::zsxs:::(ys:::zs)に等しいが、両方のオペランドはListである
    scala> List(1,2,3):::List(4,5,6)
    res9: List[Int] = List(1, 2, 3, 4, 5, 6)

    長さ
    内部定義:
      def length: Int = {
        var these = self
        var len = 0
        while (!these.isEmpty) {
          len += 1
          these = these.tail
        }
        len
      }

    だから、lengthの方法は比較的時間がかかります.
    reverse
    listを元の場所で変更するのではなく、listが可変であるため、新しいlistが返されます.
  • dropおよびtakeは、より一般化されたtailおよびinit動作
  • と理解することができる.
  • take(n)はリストの前のn要素を返し、if(n>list.length) return list
  • drop(n)はtake(n)を除くすべての要素を返し、if(n>list.length) return Nil
  • splitAt(n)は、位置nでリストを分割し、ビットメタグループを返す.(list.take(n),list.drop(n))
  • に等しい
    scala> val l1=Range(1,11).toList
    l1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> l1.take(3)
    res10: List[Int] = List(1, 2, 3)
    
    scala> l1.drop(3)
    res11: List[Int] = List(4, 5, 6, 7, 8, 9, 10)
    
    scala> l1.splitAt(3)
    res12: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5, 6, 7, 8, 9, 10))

    apply | indices
    scala> val l1=Range(1,11).toList
    l1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> l1.apply(2)
    res13: Int = 3
    
    scala> l1(2)
    res14: Int = 3
    
    scala> l1.indices
    res15: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    zip
    一致しない要素は破棄されます
    scala> val l1=Range(1,4).toList
    l1: List[Int] = List(1, 2, 3)
    
    scala> val l2=List("a","b","c","d")
    l2: List[String] = List(a, b, c, d)
    
    scala> l1.zip(l2)
    res16: List[(Int, String)] = List((1,a), (2,b), (3,c))

    mkString
    mkString([start,]seperator[,end])
    scala> val l=Range(1,5).toList
    l: List[Int] = List(1, 2, 3, 4)
    
    scala> l.mkString("start","|","end")
    res17: String = start1|2|3|4end
    
    scala> l.mkString("|")
    res18: String = 1|2|3|4

    Listクラスの高次メソッド
    foreach
    リストを巡回し、入力されたlambdaを各要素に作用させる
    内部実装:
      @inline final override def foreach[U](f: A => U) {
        var these = this
        while (!these.isEmpty) {
          f(these.head)
          these = these.tail
        }
      }

    遍歴する
    val l1 = Range(1, 11).toList
    l1.foreach(e => { print(e + " ") })
    
    l1.foreach(print(_))

    等価java 8操作
    List<Integer> list = Stream.iterate(1, i -> i + 1).limit(10)
            .collect(Collectors.toList());
    list.forEach(e -> {
        System.out.print(e + " ");
    });
    
    list.forEach(System.out::print);

    和を求める
    val l1 = Range(1, 11).toList
    var sum = 0
    l1.foreach(sum += _)
    println(sum)

    map
    パラメータf:T=>Rは、fを各要素に作用させ、タイプRの新しいリストを返す
    新しいリストを構築します.要素は元のリストの要素の2倍です.
    l1.map(e => e * 2)
    println(l1)

    等価java 8コード
    list.stream().map(e->e*2).collect(Collectors.toList());

    flatMap
    とmapタイプですが、戻りタイプに注意してください
    scala> val l=List("tom","cat","apache")
    l: List[String] = List(tom, cat, apache)
    
    scala> l.map(_.toList)
    res19: List[List[Char]] = List(List(t, o, m), List(c, a, t), List(a, p, a, c, h, e))
    
    scala> l.flatMap(_.toList)
    res20: List[Char] = List(t, o, m, c, a, t, a, p, a, c, h, e)

    filter
    scala> val l=Range(1,11).toList
    l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> l.filter(e=>(e%2)==0)
    res22: List[Int] = List(2, 4, 6, 8, 10)
    
    scala> l.filter(e=>(e&1)==0)
    res24: List[Int] = List(2, 4, 6, 8, 10)

    partition
    二元グループ(条件に合致する部分、条件に合致しない部分)を返します.
    scala> val l=Range(1,11).toList
    l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> l.partition(e=>(e%2)==0)
    res26: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))

    find
    最初の条件を満たす
    scala> l.find(e=>(e%2)==0)
    res27: Option[Int] = Some(2)

    takeWhile | dropWhile | span
  • takeWhile(p):pの最長プレフィックス組成を満たすlist
  • を返す.
  • dropWhile(p):リストのtakeWhile(n)を除く部分からなるリスト
  • を返します.
  • span:slitAtがtakeとdropを結合したのと同様に、spanがtakeWhileとdropWhileを結合した結果
  • scala> val l=List(1,2,3,-1,2,3)
    l: List[Int] = List(1, 2, 3, -1, 2, 3)
    
    scala> l.dropWhile(_>0)
    res28: List[Int] = List(-1, 2, 3)
    
    scala> l.takeWhile(_>0)
    res30: List[Int] = List(1, 2, 3)
    
    scala> l.span(_>0)
    res31: (List[Int], List[Int]) = (List(1, 2, 3),List(-1, 2, 3))

    論断(forall,exists)
    scala> val l=List(1,2,3,-1,2,3)
    l: List[Int] = List(1, 2, 3, -1, 2, 3)
    
    scala> l.forall(_>0)
    res33: Boolean = false
    
    scala> l.exists(_>0)
    res35: Boolean = true

    折りたたみ
  • 1.foldLeft(/:)

  • 内部実装:
    //  op        seed   
      override /*TraversableLike*/
      def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = { var acc = z//z     ,seed var these = this while (!these.isEmpty) { //   op     seed              seed acc = op(acc, these.head) these = these.tail } //    "  "    acc }
  • 2.foldRight(:\)

  • 内部実装:
    //     foldLeft
    //  op        seed   
    override def foldRight[B](z: B)(op: (A, B) => B): B =
      reverse.foldLeft(z)((right, left) => op(left, right))
  • 3.fold

  • 内部実装:
    //  op         
    def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

    和を求める
    val l1 = Range(1, 11).toList
    
    var sum = l1.foldLeft(0)((acc, e) => acc + e)
    println(sum) //55
    
    sum = l1./:(0)((acc, e) => acc + e)
    println(sum) //55
    
    sum = l1.foldRight(0)((e, acc) => acc + e)
    println(sum) //55
    
    sum = l1.fold(0)((acc, e) => acc + e)
    println(sum) //55
    
    sum = l1.foldLeft(0)(_ + _)
    println(sum) //55
    
    sum = l1./:(0)(_ + _)
    println(sum) //55
    
    sum = (0 /: l1)(_ + _) //    l1./:(0)
    //sum = (l1 /: 0)(_ + _) //  ,   0./:(l1)
    println(sum) //55

    var pro = 1
    val l1 = Range(1, 11).toList
    pro = l1.foldLeft(1)((acc, e) => acc * e)
    println(pro) //3628800
    
    pro = (1 /: l1)(_ * _)
    println(pro) //3628800

    ツールバーの
  • 1.sortWith(p: (Int, Int) => Boolean)
  • val l1 = Range(1, 11).toList
    
    var l2 = l1.sortWith((l, r) => l > r)
    println(l2) //List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
    
    l2 = l1.sortWith(_ > _)
    println(l2) //List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

    リストオブジェクトのメソッド