天天看點

scala的多種集合的使用(3)之周遊集合的方法

周遊集合的方法

1.用foreach循環周遊一個集合

foreach接收一個函數作為參數。定義的函數應該接收一個元素作為輸入參數,然後不要傳回任何的東西。輸入的參數的類型應該比對集合中的類型。随着foreach的執行,它每次都會把一個元素傳給你的函數,直到集合中最後一個元素。

foreach常用的就是輸出資訊:

scala> val x = Vector(1,2,3)
x: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> x.foreach((i:Int) => println(i))
1
2
3
      

對于表達式,還有其他寫法:

x.foreach(i => println(i))

x.foreach(println(_))

x.foreach(println)       

對于最後一種表達式,情況是一個隻有一條語句組成并且接受一個參數的函數可以簡寫成這種形式。

2.用for循環周遊一個集合

 可以用for循環周遊任意一種Traversable的類型。

scala> val fruits = Traversable("apple","orange","banana")
fruits: Traversable[String] = List(apple, orange, banana)

scala> for(i <- fruits) println(i)
apple
orange
banana      

如果算法很長,可以在for循環的代碼塊裡執行。

下面展示了for循環裡使用計數器的幾種方式:

scala> val fruits = Array("apple","banana","orange")
fruits: Array[String] = Array(apple, banana, orange)

scala> for(i <- 0 until fruits.size) println(s"$i is ${fruits(i)}")
0 is apple
1 is banana
2 is orange
      
scala> val fruits = Array("apple","banana","orange")
fruits: Array[String] = Array(apple, banana, orange)

scala> for((elem,count) <- fruits.zipWithIndex){
     | println(s"$count is $elem")
     | }
0 is apple
1 is banana
2 is orange
      
scala> val fruits = Array("apple","banana","orange")
fruits: Array[String] = Array(apple, banana, orange)

scala> for((elem,count) <- fruits.zip(Stream from 1)){
     | println(s"$count is $elem")
     | }
1 is apple
2 is banana
3 is orange      

3.用zipWithIndex建立循環計數器

 (1)以foreach的形式周遊集合

scala> val days = Array("Sunday","Monday","Tusday","Wednsday","Thursday","Friday","Saturday")
days: Array[String] = Array(Sunday, Monday, Tusday, Wednsday, Thursday, Friday,Saturday)

scala> days.zipWithIndex.foreach{
	 | case(day,count) => println(s"${count+1} is $day")
	 | }
1 is Sunday
2 is Monday
3 is Tusday
4 is Wednsday
5 is Thursday
6 is Friday
7 is Saturday      

 另外的一種表示方法:

scala> val days = Array("Sunday","Monday","Tusday","Wednsday","Thursday","Friday","Saturday")
days: Array[String] = Array(Sunday, Monday, Tusday, Wednsday, Thursday, Friday,Saturday)

scala> days.zipWithIndex.foreach{ d=>
	 | println(s"${d._2+1} is ${d._1}")
	 | }
1 is Sunday
2 is Monday
3 is Tusday
4 is Wednsday
5 is Thursday
6 is Friday
7 is Saturday      

(2) 以for的形式循環周遊

scala> val days = Array("Sunday","Monday","Tusday","Wednsday","Thursday","Friday","Saturday")
days: Array[String] = Array(Sunday, Monday, Tusday, Wednsday, Thursday, Friday,Saturday)

scala> for ((day,count) <- days.zipWithIndex){
	 | println(s"${count+1} is $day")
	 | }
1 is Sunday
2 is Monday
3 is Tusday
4 is Wednsday
5 is Thursday
6 is Friday
7 is Saturday      

4.用zip建立循環計數器

 在zip中使用Stream是一種生存計數器的方法。

scala> val days = Array("Sunday","Monday","Tusday","Wednsday","Thursday","Friday","Saturday")
days: Array[String] = Array(Sunday, Monday, Tusday, Wednsday, Thursday, Friday,Saturday)

scala> for ((day,count) <- days.zip(Stream from 1)){
	 | println(s"$count is $day")
	 | }
1 is Sunday
2 is Monday
3 is Tusday
4 is Wednsday
5 is Thursday
6 is Friday
7 is Saturday      

5.range循環計數器

 如果隻是需要重複做某事多次,可以用range。

scala> val fruits = Array("apple","banana","orange")
fruits: Array[String] = Array(apple, banana, orange)

scala> for(i <- 0 until fruits.size) {
	 | println(s"$i is ${fruits(i)}")}
0 is apple
1 is banana
2 is orange      

6.用reduce方法周遊集合

使用reduceLeft和reduceRight方法來周遊序列中的元素,把相鄰的元素傳給你的函數成成一個新的結果,之後和序列的下一個元素比較在生成新的結果。

reduceLeft方法是從左到右周遊一個序列,在算法中首先會對前兩個元素進行比較,然後傳回一個結果。該結果會與第三個元素進行比較,比較之後在産生一個新結果,接着在于第四個元素比較,以此類推。

scala> val a = Array(12,3,4,5,67)
a: Array[Int] = Array(12, 3, 4, 5, 67)

scala> a.reduceLeft(_ + _)
res4: Int = 91

scala> a.reduceLeft(_ min _)
res5: Int = 3

scala> a.reduceLeft(_ max _)
res6: Int = 67      

這裡面的兩個下劃線,它們代表傳給函數的兩個參數。

reduceRight與reduceLeft同理的。

7.用fold方法周遊集合

foldLeft方法如同reduceLeft,它會設定一個種子值用于第一個元素。foldLeft接收兩個參數清單。第一個清單有一個字段,種子值。第二個清單是要運作的代碼塊。

scala> val a = Array(12,3,4,5,67)
a: Array[Int] = Array(12, 3, 4, 5, 67)

scala> a.reduceLeft(_ + _)
res8: Int = 91

scala> a.foldLeft(20)(_ + _)
res9: Int = 111      

我們來看一下foldLeft和foldRight的執行過程:  

下面的/:是foldLeft的簡化版。

scala> ((1 to 4).foldLeft(5))((i,sum) => i-sum)
res25: Int = -5

scala> (1 to 4).foldLeft(5)(_-_)
res8: Int = -5

scala> (5/:(1 to 4))(_-_)
res9: Int = -5      

foldLeft的執行過程:5-1-2-3-4=-5

下面的:\是foldRight的簡化版。

scala> ((1 to 4).foldRight(5))((i,sum) => i-sum)
res22: Int = 3

scala> (1 to 4).foldRight(5)(_-_)
res14: Int = 3

scala> ((1 to 4):\5)(_-_)
res15: Int = 3      

foldRight的執行過程:1-(2-(3-(4-(5-0))))=3