ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

scala中集合的常用方法

2019-03-22 22:48:57  阅读:216  来源: 互联网

标签:常用 val scala ## List println coll 集合 def


注:val map = Map((“b”,2),(“a”,1),(“d”,4)),这里调用的方法是使用map调用的

1. 最大值最小值
方法:max、min、maxBy、minBy

def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A = {
  if (isEmpty)
    throw new UnsupportedOperationException("empty.minBy")

  reduceLeft((x, y) => if (cmp.lteq(f(x), f(y))) x else y)
}
  case class Book(title: String, pages: Int) 
  val books = Seq( Book("Future of Scala developers", 85), 
                  Book("Parallel algorithms", 240), 
                  Book("Object Oriented Programming", 130), 
                  Book("Mobile Development", 495) ) 
  //Book(Mobile Development,495) 
  books.maxBy(book => book.pages) 
  //Book(Future of Scala developers,85) 
  books.minBy(book => book.pages)

如上所示,minBy & maxBy 方法解决了复杂数据的问题。你只需选择决定数据最大或最小的属性。

2.过滤
方法:filter、filterNot

/** Selects all elements of this $coll which satisfy a predicate.
*
 *  @param p     the predicate used to test elements.
 *  @return      a new $coll consisting of all elements of this $coll that satisfy the given
 *               predicate `p`. The order of the elements is preserved.
 */
def filter(p: A => Boolean): Repr = {
  val b = newBuilder
  for (x <- this)
    if (p(x)) b += x
  b.result
}

3.Flatten
方法:flatten
flatten可以把嵌套的结构展开.

/** Converts this $coll of traversable collections into
 *  a $coll formed by the elements of these traversable
 *  collections.
 *
 *  @tparam B the type of the elements of each traversable collection.
 *  @param asTraversable an implicit conversion which asserts that the element
 *          type of this $coll is a `GenTraversable`.
 *  @return a new $coll resulting from concatenating all element ${coll}s.
 *
 *  @usecase def flatten[B]: $Coll[B]
 *
 *    @inheritdoc
 *
 *    The resulting collection's type will be guided by the
 *    static type of $coll. For example:
 *
 *    {{{
 *    val xs = List(Set(1, 2, 3), Set(1, 2, 3))
 *    // xs == List(1, 2, 3, 1, 2, 3)
 *
 *    val ys = Set(List(1, 2, 3), List(3, 2, 1))
 *    // ys == Set(1, 2, 3)
 *    }}}
 */
def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
  val b = genericBuilder[B]
  for (xs <- sequential)
    b ++= asTraversable(xs).seq
  b.result
}

4.Euler Diagram
[译者注:Euler Diagram 可以翻译为欧拉图,但请注意与 Euler Graph 的区别。Euler Diagram 用于描述集合及集合间的关系,而 Euler Graph 描述的是一种“图”这样的数据结构]
方法:diff、intersect、union(可以联合distinct一起使用)

5.map(映射)列表元素
方法:map
map 函数的逻辑是遍历集合中的元素并对每个元素调用函数。你也可以不调用任何函数,保持返回元素本身,但这样 map 无法发挥作用,因为你在映射过后得到的是同样的集合。

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
  def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
    val b = bf(repr)
    b.sizeHint(this)
    b
  }
  val b = builder
  for (x <- this) b += f(x)
  b.result
}

6.flatmap
方法:flatMap(map & flatten组成)
flatMap结合了map和flatten的功能。接收一个可以处理嵌套列表的函数,然后把返回结果连接起来。

def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
  def builder = bf(repr) // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
  val b = builder
  for (x <- this) b ++= f(x).seq
  b.result
}

flatmap是先map再flatten

object collection_t1 {

  def flatMap1(): Unit = {
    val li = List(1,2,3)
    val res = li.flatMap(x => x match {
      case 3 => List('a','b')
      case _ => List(x*2)
    })
    println(res)
  }

  def map1(): Unit = {
    val li = List(1,2,3)
    val res = li.map(x => x match {
      case 3 => List('a','b')
      case _ => x*2
    })
    println(res)
  }

  def main(args: Array[String]): Unit = {
    flatMap1()
    map1()
  }
}

将代码run起来,最后输出为:
List(2, 4, a, b)
List(2, 4, List(a, b))

7.对整个集合进行条件检查
方法:forall
有一个场景大家都知道,即确保集合中所有元素都要符合某些要求,如果有哪怕一个元素不符合条件,就需要进行一些处理:

val numbers = Seq(3, 7, 2, 9, 6, 5, 1, 4, 2) 
  //ture numbers.forall(n => n < 10) 
  //false numbers.forall(n => n > 5)

而 forall 函数就是为处理这类需求而创建的。

8.定义集合进行分组
方法:partition
你是否尝试过将一个集合按一定的规则拆分成两个新的集合?比如,我们把某个集合拆分成偶数集和奇数集,partition 函数可以帮我们做到这一点

/** Partitions this $coll in two ${coll}s according to a predicate.
 *
 *  @param p the predicate on which to partition.
 *  @return  a pair of ${coll}s: the first $coll consists of all elements that
 *           satisfy the predicate `p` and the second $coll consists of all elements
 *           that don't. The relative order of the elements in the resulting ${coll}s
 *           is the same as in the original $coll.
 */
def partition(p: A => Boolean): (Repr, Repr) = {
  val l, r = newBuilder
  for (x <- this) (if (p(x)) l else r) += x
  (l.result, r.result)
}

9.fold
方法:fold、foldLeft、foldRight
fold: fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1 带有初始值的reduce,从一个初始值开始,从左向右将两个元素合并成一个,最终把列表合并成单一元素。

val nums = List(1, 2, 3)
nums.fold(1)((a, b) => {
  println(s"$a - $b")
  a + b
})
println("#############")
nums.foldLeft(1)((a, b) => {
  println(s"$a - $b")
  a + b
})
println("#############")
nums.foldRight(1)((a, b) => {
  println(s"$a - $b")
  a + b
})

结果:
1 - 1
2 - 2
4 - 3
#############
1 - 1
2 - 2
4 - 3
#############
3 - 1
2 - 4
1 - 6

注:两个值的结合还是从左到右,也就是op的左右不会因为left、right而不同

10.reduce
方法:reduce、reduceLeft、reduceRight

reduceLeft: reduceLeft[B >: A](f: (B, A) ⇒ B): B
reduceRight: reduceRight[B >: A](op: (A, B) ⇒ B): B

reduceLeft从列表的左边往右边应用reduce函数,reduceRight从列表的右边往左边应用reduce函数

val nums1 = List(2.0,2.0,3.0)

val resultLeftReduce = nums1.reduceLeft((a,b) =>{
  println(s"$a - $b")
  math.pow(a,b)
})  // = pow( pow(2.0,2.0) , 3.0) = 64.0
println(resultLeftReduce)

val resultRightReduce =
  nums1.reduceRight((a,b) =>{
    println(s"$a - $b")
    math.pow(a,b)}) // = pow(2.0, pow(2.0,3.0)) = 256.0

2.0,2.0,3.0
执行过程:
reduceLeft:
2.0 - 2.0
4.0 - 3.0
64.0
reduceRight:(两个值的结合还是从左到右,也就是op的左右不会因为left、right而不同)
2.0 - 3.0
2.0 - 8.0

11.aggregate
方法:

/**
Aggregate the elements of each partition, and then the results for all the 
partitions, using given combine functions and a neutral "zero value". This 
function can return a different result type, U, than the type of this RDD, 
T. Thus, we need one operation for merging a T into an U and one operation 
for merging two U's, as in Scala.TraversableOnce. Both of these functions 
are allowed to modify and return their first argument instead of creating a 
new U to avoid memory allocation. 
*/
def aggregate[U](zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)(implicit arg0: ClassTag[U]): U
//假如List(1,2,3,4,5,6,7,8,9,10),对List求平均数,使用aggregate可以这样操作。
val rdd = List(1,2,3,4,5,6,7,8,9)
//(0,0) = (和,个数) 元组第一个值是求和的结果,第二个值是计数的结果
val tuple = rdd.par.aggregate((1, 1))(
//acc是初始值(也就是元组),number是集合的一个元素
  (acc, number) => {
    println(s"## $acc - $number => ("
      +(acc._1 + number)+" , "+(acc._2 + 1) +")")
    (acc._1 + number, acc._2 + 1)
  },

  (par1, par2) => {
    println(s"** $par1 - $par2 => ("
      +(par1._1 + par2._1)+" , " +(par1._2 + par2._2) +")")
    (par1._1 + par2._1, par1._2 + par2._2)
  }

)
println(tuple)

执行结果:(par多线程执行)
##(1,1) - 5 => (6 , 2) #一个分区(因为有(1,1))
##(1,1) - 6 => (7 , 2) #一个分区
** (6,2) - (7,2) => (13 , 4)
##(1,1) - 8 => (9 , 2) #一个分区
##(1,1) - 9 => (10 , 2) #一个分区
##(1,1) - 1 => (2 , 2) #一个分区
##(1,1) - 2 => (3 , 2) #一个分区
** (9,2) - (10,2) => (19 , 4)
** (2,2) - (3,2) => (5 , 4)
##(1,1) - 4 => (5 , 2) #一个分区
##(1,1) - 3 => (4 , 2) #一个分区
** (4,2) - (5,2) => (9 , 4)
** (5,4) - (9,4) => (14 , 8)
##(1,1) - 7 => (8 , 2) #一个分区
** (8,2) - (19,4) => (27 , 6)
** (13,4) - (27,6) => (40 , 10)
** (14,8) - (40,10) => (54 , 18)
(54,18)

单线程的运行(无par)
##(1,1) - 1 => (2 , 2)
##(2,2) - 2 => (4 , 3)
##(4,3) - 3 => (7 , 4)
##(7,4) - 4 => (11 , 5)
##(11,5) - 5 => (16 , 6)
##(16,6) - 6 => (22 , 7)
##(22,7) - 7 => (29 , 8)
##(29,8) - 8 => (37 , 9)
##(37,9) - 9 => (46 , 10)
(46,10)

12.foreach
方法:foreach
foreach和map相似,只不过它没有返回值,foreach只是为了对参数进行作用。

/** Applies a function `f` to all values produced by this iterator.
 *
 *  @param  f   the function that is applied for its side-effect to every element.
 *              The result of function `f` is discarded.
 *
 *  @tparam  U  the type parameter describing the result of function `f`.
 *              This result will always be ignored. Typically `U` is `Unit`,
 *              but this is not necessary.
 *
 *  @note    Reuse: $consumesIterator
 *
 *  @usecase def foreach(f: A => Unit): Unit
 *    @inheritdoc
 */
def foreach[U](f: A =>  U) { while (hasNext) f(next()) }

13.groupBy
方法:groupBy

补充:https://blog.csdn.net/pzw_0612/article/details/45936165

标签:常用,val,scala,##,List,println,coll,集合,def
来源: https://blog.csdn.net/z1941563559/article/details/88751914

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有