【2019-05-28】scala使用列表

2019-05-28  本文已影响0人  BigBigFlower

列表是同质的:列表的所有元素都具有相同的类型。元素类型为T的列表类型写成 List[T]。

//列表字面量
object Misc {
  val fruit = List("apples", "oranges", "pears")
  val nums = List(1, 2, 3, 4)
  val diag3 =
    List(
      List(1, 0, 0),
      List(0, 1, 0),
      List(0, 0, 1)
    )
  val empty = List()

  object ExplicitTypes {
    val fruit: List[String] = List("apples", "oranges", "pears")
    val nums: List[Int] = List(1, 2, 3, 4)
    val diag3: List[List[Int]] =
      List(
        List(1, 0, 0),
        List(0, 1, 0),
        List(0, 0, 1)
      )
    val empty: List[Nothing] = List()
  }

  // List() is also of type List[String]!
  val xs: List[String] = List()  
//构造列表,所有的列表都是由两个基础构造Nil(空列表)和::(中缀操作符,表示列表从前端构造)构造出来的。
  object ExplicitCons {
    val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
//fruit: List[String] = List(apples, oranges, pears)
    val nums  = 1 :: (2 :: (3 :: (4 :: Nil)))
    val diag3 = (1 :: (0 :: (0 :: Nil))) ::
                (0 :: (1 :: (0 :: Nil))) ::
                (0 :: (0 :: (1 :: Nil))) :: Nil
    val empty = Nil
  }
 
  object NoParens {
    val nums = 1 :: 2 :: 3 :: 4 :: Nil
  }

  def append[T](xs: List[T], ys: List[T]): List[T] =
    xs match { 
      case List() => ys
      case x :: xs1 => x :: append(xs1, ys)
    }

  def msort[T](less: (T, T) => Boolean)
      (xs: List[T]): List[T] = {
  
    def merge(xs: List[T], ys: List[T]): List[T] =
      (xs, ys) match {
        case (Nil, _) => ys
        case (_, Nil) => xs
        case (x :: xs1, y :: ys1) =>
          if (less(x, y)) x :: merge(xs1, ys)
          else y :: merge(xs, ys1)
      }
  
    val n = xs.length / 2
    if (n == 0) xs
    else {
      val (ys, zs) = xs splitAt n
      merge(msort(less)(ys), msort(less)(zs))
    }
  }

  def assoc = {
    val xs = List("x")
    val ys = List("y")
    val zs = List("z")
    val l1 =
      xs ::: ys ::: zs
    val l2 =
      xs ::: (ys ::: zs)
    l1 == l2
  }

  def forList = {
    for (i <- List.range(1, 5); j <- List.range(1, i)) yield (i, j)
  }

  def main(args: Array[String]) {
    println("assoc [" + assoc + "]")
    println("msort((x: Int, y: Int) => x < y)(List(5, 7, 1, 3)) [" +
             msort((x: Int, y: Int) => x < y)(List(5, 7, 1, 3)) + "]")

    println("forList [" + forList + "]")
  }
}

列表的基本操作
head:返回第一个元素
tail:返回除第一个元素之外的所有元素
isEmpty:如果列表为空,则返回真

object InsertionSort1 {
  def isort(xs: List[Int]): List[Int] =
    if (xs.isEmpty) Nil
    else insert(xs.head, isort(xs.tail))
  
  def insert(x: Int, xs: List[Int]): List[Int] = 
    if (xs.isEmpty || x <= xs.head) x :: xs
    else xs.head :: insert(x, xs.tail)

  def main(args: Array[String]) {
    println("isort(List(5, 3, 12)) [" + isort(List(5, 3, 12)) + "]")
  }
}

列表模式
列表还可以使用模式匹配做拆分

val List(a, b, c) = fruit
//a: String = apples
//b: String = oranges
//c: String = pears
val a :: b :: rest = fruit
//a: String = apples
//b: String = oranges
//rest: List[String] = List(pears)

list类的一阶方法first-order

//连接列表
//连接操作:::被实现为list类的方法
List(1, 2) ::: List(3, 4, 5)
//res5: List[Int] = List(1, 2, 3, 4, 5)
//分治原则
 def append[T](xs: List[T], ys: List[T]): List[T] =
    xs match { 
      case List() => ys
      case x :: xs1 => x :: append(xs1, ys)
    }
//计算列表的长度
 List(1, 2, 3).length
//res6: Int = 3
//访问列表的尾部:init方法和last方法
val abcde = List('a', 'b', 'c', 'd', 'e')
abcde.last
//res7: Char = e
abcde.init
//res8: List[Char] = List(a, b, c, d)
//反转列表
 abcde.reverse 
//res9: List[Char] = List(e, d, c, b, a)
//前缀与后缀
abcde take 2
//res10: List[Char] = List(a, b)
abcde drop 2
//res11: List[Char] = List(c, d, e)
abcde splitAt 2
//res12: (List[Char], List[Char]) = (List(a, b),List(c, d, e))
//元素选择
abcde apply 2
//res13: Char = c
abcde(2)      // rare in Scala
//res14: Char = c
abcde.indices
//res13: List[Int] = List(0, 1, 2, 3, 4)
//啮齿列表,zip操作可以把两个列表组成一个对偶列表
abcde.indices zip abcde
//res15: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((0,a), (1,b), (2,c), (3,d), (4,e))
//如果两个列表的长度不一致,那么任何不匹配的元素将被丢掉
val zipped = abcde zip List(1, 2, 3)
//zipped: List[(Char, Int)] = List((a,1), (b,2), (c,3))
abcde.zipWithIndex
//res15: List[(Char, Int)] = List((a,0), (b,1), (c,2), (d,3), (e,4))
//显示列表
abcde.toString
//res16: String = List(a, b, c, d, e)
abcde mkString ("[", ",", "]")
//res17: String = [a,b,c,d,e]

List类的高阶方法

//列表间映射:map、flatMap、foreach
//xs map f操作类型为List[T]的列表xs和类型为T=>U的函数f为操作元
List(1, 2, 3) map (_ + 1)
//res16: List[Int] = List(2, 3, 4)
val words = List("the", "quick", "brown", "fox")
words map (_.length)
//res2: List[Int] = List(3, 5, 5, 3)
words map (_.toList.reverse.mkString)
//res3: List[String] = List(eht, kciuq, nworb, xof)
//flatMap操作符和map操作符类似,不过它的右操作元是能够返回元素列表的元素。它对列表的每个元素调用该方法然后连接所有方法的结果并返回。
words map (_.toList)
//res4: List[List[Char]] = List(List(t, h, e), List(q, u, i, c, k), List(b, r, o, w, n), List(f, o, x))
words flatMap (_.toList)
//res5: List[Char] = List(t, h, e, q, u, i, c, k, b, r, o, w, n, f, o, x)
//构建所有的i<=j<i<5的(i,j)对偶
List.range(1,5) flatMap(i=>List.range(1,i)map(j=>(i,j)))
//res7: List[(Int, Int)] = List((2,1), (3,1), (3,2), (4,1), (4,2), (4,3))
 var sum = 0
//sum: Int = 0
List(1, 2, 3, 4, 5) foreach (sum += _)
 sum
//res30: Int = 15
//列表过滤:filter、partition、find、takeWhile、dropWhile和span
//xs filter p 操作类型为List[T]的列表xs和类型为T=>Boolean的论断函数为操作元
List(1, 2, 3, 4, 5) filter (_ % 2 == 0)
//res31: List[Int] = List(2, 4) 
 words filter (_.length == 3)
//res32: List[String] = List(the, fox)
//partition方法和filter方法类似,不过返回的列表对,一个包含所有论断为真的元素,一个包含论断为假的元素
List(1, 2, 3, 4, 5) partition (_ % 2 == 0)
//res33: (List[Int], List[Int]) = (List(2, 4),List(1, 3, 5))
//find返回第一个满足给定论断的元素
List(1, 2, 3, 4, 5) find (_ % 2 == 0)
//res36: Option[Int] = Some(2)
List(1, 2, 3, 4, 5) find (_ >= 0)
//res37: Option[Int] = Some(1)
//xs takeWhile p操作返回列表中最长的能够满足p的前缀
List(1, 2, 3, -4, 5) takeWhile (_ > 0)
//res34: List[Int] = List(1, 2, 3)
//xs dropWhile p移除最长的能够满足p的前缀
words dropWhile (_ startsWith "t")
//res35: List[String] = List(quick, brown, fox)
//xs span p 等价于(xs takeWhile p,xs dropWhile p)
List(1, 2, 3, -4, 5) span (_ > 0)
//res38: (List[Int], List[Int]) = (List(1, 2, 3),List(-4, 5))
//列表的论断:forall 和exists
//操作xs forall p以列表xs和论断p为参数,如果列表的所有元素满足p则返回true
def hasZeroRow(m: List[List[Int]]) =m exists (row => row forall (_ == 0))
//hasZeroRow: (m: List[List[Int]])Boolean
hasZeroRow(List(List(1,2,3)))
//res45: Boolean = false
hasZeroRow(List(List(0,1,2,3)))
//res46: Boolean = false
hasZeroRow(List(List(0)))
//res47: Boolean = true
//折叠列表/:和:\
//左折叠(fold left)操作"(z /: xs)(op)":开始值z,列表xs,二元操作op,折叠的结果是op应用到前缀z及每个相邻元素上
//即:(z /: List(a,b,c))(op)=op(op(op(z,a),b),c)
//words  List[String] = List(the, quick, brown, fox)
("" /: words) (_ +" "+ _)
//res48: String = " the quick brown fox"
//去掉最开始的空格
(words.head /: words.tail)  (_ +" "+ _)
//res50: String = the quick brown fox
//:\右操作符同理
//(List(a,b,c):\z)(op)=op(a,op(b,op(c,z)))
//列表排序sort
//sorted
List(1, -3, 4, 2, 6).sorted
//res55: List[Int] = List(-3, 1, 2, 4, 6)
//sortBy
List(1, -3, 4, 2, 6).sortBy(d=>d)//升序
//res58: List[Int] = List(-3, 1, 2, 4, 6)
List(1, -3, 4, 2, 6).sortBy(d=>d).reverse//降序
//res63: List[Int] = List(6, 4, 2, 1, -3)
//sortWith
val xs=Seq(1,5,3,4,6,2)
//xs: Seq[Int] = List(1, 5, 3, 4, 6, 2)
xs.sortWith(_<_) 
//res64: Seq[Int] = List(1, 2, 3, 4, 5, 6)

List对象方法

//通过元素创建列表:List.apply
List.apply(1, 2, 3)
//创建数值范围:List.range
List.range(1, 5)
//res65: List[Int] = List(1, 2, 3, 4)
List.range(1, 9, 2)
//res66: List[Int] = List(1, 3, 5, 7)
List.range(9, 1, -3)
//res67: List[Int] = List(9, 6, 3)
//创建统一的列表:List.fill
//比较早的版本是make(5,'a'),后更新为fill(5)('a')
List.fill(5)('a')
//res70: List[Char] = List(a, a, a, a, a)
//每个重复3次,重复5遍
List.fill(5,3)('a')
//res73: List[List[Char]] = List(List(a, a, a), List(a, a, a), List(a, a, a), List(a, a, a), List(a, a, a))

//解除啮合列表:List.unzip
//压缩
val zipped = "abcde".toList zip List(1, 2, 3)
//zipped: List[(Char, Int)] = List((a,1), (b,2), (c,3))
//解压
zipped.unzip
//res74: (List[Char], List[Int]) = (List(a, b, c),List(1, 2, 3))

//连接列表:List.flatten、List.concat
val xss = List(List('a', 'b'), List('c'), List('d', 'e'))
//xss: List[List[Char]] = List(List(a, b), List(c), List(d, e))
xss.flatten
//res76: List[Char] = List(a, b, c, d, e)
List.concat(List('a', 'b'), List('c'))
//res77: List[Char] = List(a, b, c)

上一篇 下一篇

猜你喜欢

热点阅读