美文网首页
Scala集合

Scala集合

作者: allenggg | 来源:发表于2018-03-18 11:26 被阅读0次

    附上Effective Scala:Effective Scala
    学习笔记摘抄于Twitter scala文档:Twitter.github.io
    为了方便,本文中类的定义代码和调用代码同放一处;
    实际上,代码的调用需要写在程序入口(main方法)

    一、Basic Data Structures

    Arrays

    Arrays preserve order, can contain duplicates, and are mutable.(有序,可重复,可修改)

    val numbers = Array(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
    val two = numbers(1)
    

    Lists

    Lists preserve order, can contain duplicates, and are immutable.(有序,可重复,不可修改)

    val numbers = List(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
    numbers(3) = 10
    <console>:9: error: value update is not a member of List[Int]
                 numbers(3) = 10
    

    Sets

    Sets do not preserve order and have no duplicates.(无序,不重复)

    val numbers = Set(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
    println(numbers) //Set(5, 1, 2, 3, 4)
    

    Tuple

    A tuple groups together simple logical collections of items without using a class.
    Unlike case classes, they don’t have named accessors, instead they have accessors that are named by their position and is 1-based rather than 0-based.(下标从1开始)

    val hostPort = ("localhost", 80)
    val host = hostPort._1
    val port = hostPort._2
    

    Tuples fit with pattern matching nicely.

    hostPort match {
      case ("localhost", port) => ...
      case (host, port) => ...
    }
    

    Tuple has some special sauce for simply making Tuples of 2 values:->

    val t  = 1 -> 2
    println(t) //(1,2)
    

    Maps

    Map(1 -> 2, 2 -> 3) //or Map((1,2), (2,3)) 
    Map("foo" -> "bar")
    Map(1 -> Map("foo" -> "bar")) //value is a  map
    Map("timesTwo" -> { timesTwo(_) }) //value is a function
    

    This looks like special syntax but remember back to our discussion of Tuple that -> can be used to create Tuples.

    Option

    Option is a container that may or may not hold something.
    The basic interface for Option looks like:

    trait Option[T] {
      def isDefined: Boolean
      def get: T
      def getOrElse(t: T): T
    }
    

    Option itself is generic and has two subclasses: Some[T] or None

    val numbers = Map("one" -> 1, "two" -> 2)
    val res = numbers.get("two")  //Some(2)
    val res1 = numbers.get("Two") //None
    

    getOrElse lets you easily define a default value.

    val result = res1.getOrElse(0) * 2
    

    二、Functional Combinators(组合子)

    map

    Evaluates a function over each element in the list, returning a list with the same number of elements.

    val numbers = List(1, 2, 3, 4)
    numbers.map((i: Int) => i * 2)
    
    def timesTwo(i: Int): Int = i * 2
    numbers.map(timesTwo) //pass in a function 
    

    foreach

    foreach is like map but returns nothing. foreach is intended for side-effects only.

    numbers.foreach((i: Int) => i * 2)
    

    filter

    removes any elements where the function you pass in evaluates to false. Functions that return a Boolean are often called predicate(谓语) functions.

    val newNumbers = numbers.filter((i: Int) => i % 2 == 0)  //List(2, 4)
    
    def isEven(i: Int): Boolean = i % 2 == 0
    numbers.filter(isEven)
    

    zip

    zip aggregates the contents of two lists into a single list of pairs.

    List(1, 2, 3).zip(List("a", "b", "c")) //List((1,a), (2,b), (3,c))
    

    partition

    partition splits a collection based on where it falls with respect to a predicate function.
    partition将使用给定的谓词函数分割列表。

    val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    numbers.partition(_ % 2 == 0)) //(List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))
    

    find

    find returns the first element of a collection that matches a predicate function.

    numbers.find((i: Int) => i > 5)  //Some(6)
    

    drop & dropWhile

    drop drops the first i elements
    dropWhile removes the first elements that match a predicate function. For example, if we dropWhile odd numbers from our list of numbers, 1 gets dropped (but not 3 which is “shielded” by 2).
    dropWhile 将删除元素直到找到第一个匹配谓词函数的元素。例如,如果我们在numbers列表上使用dropWhile奇数的函数, 1将被丢弃(但3不会被丢弃,因为他被2“保护”了)。

    numbers.drop(5) //List(6, 7, 8, 9, 10)
    numbers.dropWhile(_ % 2 != 0)  //List(2, 3, 4, 5, 6, 7, 8, 9, 10)
    

    foldLeft

    numbers.foldLeft(0)((m: Int, n: Int) => m + n) //55
    

    0 is the starting value (Remember that numbers is a List[Int]), and m
    acts as an accumulator.

    scala> numbers.foldLeft(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n }
    m: 0 n: 1
    m: 1 n: 2
    m: 3 n: 3
    m: 6 n: 4
    m: 10 n: 5
    m: 15 n: 6
    m: 21 n: 7
    m: 28 n: 8
    m: 36 n: 9
    m: 45 n: 10
    res0: Int = 55
    

    foldRight

    Is the same as foldLeft except it runs in the opposite direction.

    scala> numbers.foldRight(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n }
    m: 10 n: 0
    m: 9 n: 10
    m: 8 n: 19
    m: 7 n: 27
    m: 6 n: 34
    m: 5 n: 40
    m: 4 n: 45
    m: 3 n: 49
    m: 2 n: 52
    m: 1 n: 54
    res0: Int = 55
    

    flatten

    flatten collapses one level of nested structure.

    List(List(1, 2), List(3, 4)).flatten //List(1, 2, 3, 4)
    

    flatMap

    flatMap is a frequently used combinator that combines mapping and flattening. flatMap takes a function that works on the nested lists and then concatenates the results back together.

    val nestedNumbers = List(List(1, 2), List(3, 4))
    nestedNumbers.flatMap(x => x.map(_ * 2)) //List(2, 4, 6, 8)
    nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten ////List(2, 4, 6, 8)
    

    Think of it as short-hand for mapping and then flattening.

    Generalized functional combinators

    Interestingly, every functional combinator shown above can be written on top of fold.

    def ourMap(numbers: List[Int], fn: Int => Int): List[Int] = {
      numbers.foldRight(List[Int]()) { (x: Int, xs: List[Int]) =>
        fn(x) :: xs
      }
    }
    
    ourMap(numbers, timesTwo(_)) //List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
    

    Why List[Int]()? Scala wasn’t smart enough to realize that you wanted an empty list of Ints to accumulate into.

    Maps?

    All of the functional combinators shown work on Maps, too
    Map可以被看作是一个二元组的列表,所以你写的函数要处理一个键和值的二元组。

    val extensions = Map("steve" -> 100, "bob" -> 101, "joe" -> 201)
    
    extensions.filter((namePhone: (String, Int)) => namePhone._2 < 200) //Map((steve,100), (bob,101))
    extensions.filter({case (name, extension) => extension < 200}) //Map((steve,100), (bob,101))
    

    相关文章

      网友评论

          本文标题:Scala集合

          本文链接:https://www.haomeiwen.com/subject/uqheqftx.html