scala把序列分解成子集(group by,partition)
Problem
????你想要基于一種算法或者規則,把一個序列切分為兩個或者多個子集。
Solution
????使用groupBy,partition,span,splitAt方法可以把一個集合切分成子集合。sliding和unzip方法也可以用來把集合切分成子集合,盡管sliding可以產生許多子序列,unzip則主要用來拆分二元祖。
????groupy,partition和span方法可以讓你把一個集合按一個方法定義切分成子集合,splitAt讓你按集合下標切分一個集合為兩個子集合:
scala>?val?x?=?List(15,?10,?5,?8,?20,?12) x:?List[Int]?=?List(15,?10,?5,?8,?20,?12) scala>?x.groupBy(_?>?10) res19:?scala.collection.immutable.Map[Boolean,List[Int]]?=?Map(false?->?List(10,?5,?8),?true?->?List(15,?20,?12))scala>?x.partition(_?>?10) res20:?(List[Int],?List[Int])?=?(List(15,?20,?12),List(10,?5,?8))scala>?x.partition(_?>?10) res20:?(List[Int],?List[Int])?=?(List(15,?20,?12),List(10,?5,?8))scala>?x.span(_?<?20) res21:?(List[Int],?List[Int])?=?(List(15,?10,?5,?8),List(20,?12))scala>?x.splitAt(2) res22:?(List[Int],?List[Int])?=?(List(15,?10),List(5,?8,?20,?12))????groupBy(p)方法會把一個集合根據你提供的方法切分成一個map。Map中key=true對應的value是所有使p返回true的集合元素組成的新集合,key=flase對應的value是所有使p返回false的元素組成的新集合。
????方法partition(p),span(p)和splitAt(n)會創建一個二元祖,二元祖的每個元素都是和原集合類型相同的集合。partiton會把集合的所有元素遍歷一遍,滿足條件p的元素進二元祖第一個集合,不滿足條件p的元素進二元祖第二個集合。span方法會從集合頭部開始遍歷直到第一個不滿足p的元素為止,所有滿足p的進第一個集合,不滿足p的進第二個集合。splitAt可以認為前n個元素進第一個集合,剩余元素進第二個集合。
????我們可以用下面這種方式來接收返回值:
scala>?val?(a,b)?=?x.partition(_?>?10) a:?List[Int]?=?List(15,?20,?12) b:?List[Int]?=?List(10,?5,?8)scala>?a res23:?List[Int]?=?List(15,?20,?12)scala>?b res24:?List[Int]?=?List(10,?5,?8)????我們可以用下面的形式接收groupBy方法的返回值:
scala>?val?groups?=?x.groupBy(_?>?10) groups:?scala.collection.immutable.Map[Boolean,List[Int]]?=?Map(false?->?List(10,?5,?8),?true?->?List(15,?20,?12))scala>?val?trues?=?groups(true) trues:?List[Int]?=?List(15,?20,?12)scala>?val?falses?=?groups(false) falses:?List[Int]?=?List(10,?5,?8)????窗口方法sliding(w,s),w是窗口大小,s是每次滑動距離。使用這個方法,就是下標從0開始,每次向后移動s距離,每次取當前下標開始的w個元素,組成一個新的集合。
scala>?val?nums?=?(1?to?5).toArray nums:?Array[Int]?=?Array(1,?2,?3,?4,?5)scala>?nums.sliding(2) res25:?Iterator[Array[Int]]?=?non-empty?iteratorscala>?nums.sliding(2).toList res26:?List[Array[Int]]?=?List(Array(1,?2),?Array(2,?3),?Array(3,?4),?Array(4,?5))scala>?nums.sliding(2,2).toList res27:?List[Array[Int]]?=?List(Array(1,?2),?Array(3,?4),?Array(5))scala>?nums.sliding(2,3).toList res28:?List[Array[Int]]?=?List(Array(1,?2),?Array(4,?5))????unzip方法處理二元祖集合,它可以把二元祖里的第一個元素歸為一個集合,二元祖里的第二個元素歸為第二個集合:
scala>?val?listOfTuple2s?=?List((1,2),?('a',?'b')) listOfTuple2s:?List[(AnyVal,?AnyVal)]?=?List((1,2),?(a,b))scala>?val?x?=?listOfTuple2s.unzip x:?(List[AnyVal],?List[AnyVal])?=?(List(1,?a),List(2,?b))????下面這個例子中,我們使用unzip方法來把couples集合中丈夫和妻子分到兩個集合中:
scala>?val?couples?=?List(("Kim",?"Al"),?("Julia",?"Terry")) couples:?List[(String,?String)]?=?List((Kim,Al),?(Julia,Terry))scala>?val?(women,?men)?=?couples.unzip women:?List[String]?=?List(Kim,?Julia) men:?List[String]?=?List(Al,?Terry)????unzip正好是zip的反方法:
scala>?List(1,2,3).zip(List(4,5,6)) res30:?List[(Int,?Int)]?=?List((1,4),?(2,5),?(3,6))scala>?List(1,2,3).zip(List(4,5,6)).unzip res31:?(List[Int],?List[Int])?=?(List(1,?2,?3),List(4,?5,?6))總結
以上是生活随笔為你收集整理的scala把序列分解成子集(group by,partition)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scikit-learn学习笔记(四)R
- 下一篇: scala使用reduce和fold方法