zoukankan      html  css  js  c++  java
  • 【转】Scala reduceLeft examples

    原文链接 http://alvinalexander.com/scala/scala-reduceleft-examples

    The reduceLeft method on the Scala collections is fun. Just start with a collection:

    scala> val a = Array(20, 12, 6, 15, 2, 9)
    a: Array[Int] = Array(20, 12, 6, 15, 2, 9)
    

    Then give reduceLeft a simple function to work with, and let it do its thing:

    scala> a.reduceLeft(_ + _)
    res0: Int = 64
    
    scala> a.reduceLeft(_ * _)
    res1: Int = 388800
    
    scala> a.reduceLeft(_ min _)
    res2: Int = 2
    
    scala> a.reduceLeft(_ max _)
    res3: Int = 20
    

    Use a function

    When your comparison operation gets long, just create a function first, then pass the function intoreduceLeft:

    scala> val a = Array(20, 12, 6, 15, 2, 9)
    a: Array[Int] = Array(20, 12, 6, 15, 2, 9)
    
    scala> val f = (x:Int, y:Int) => x max y
    f: (Int, Int) => Int = <function2>
    
    scala> a.reduceLeft(f)
    res0: Int = 20
    

    Admittedly that was a simple function, but we'll look at a longer one next.

    How reduceLeft works

    The reduceLeft method words by applying the function/operation you give it, and applying it to successive elements in the collection. The result of the first comparison is used in the second comparison, and so on. It works from left to right, beginning with the first element in the collection.

    We can demonstrate this by creating a bigger function now. We'll do a max comparison like we did earlier, but now we'll add some debugging code to the function so we can see how reduceLeft works. Here's the function:

    // returns the max of the two elements
    val findMax = (x: Int, y: Int) => {
      val winner = x max y
      println("compared %d to %d, %d was larger".format(x,y,winner))
      winner
    }
    

    Next, let's move the numbers in the array around a little bit, so the output will be more interesting:

    val a = Array(12, 6, 15, 2, 20, 9)
    

    Now we call reduceLeft on our new array, giving it our new function, and we see how reduceLeftworks:

    scala> a.reduceLeft(findMax)
    compared 12 to 6, 12 was larger
    compared 12 to 15, 15 was larger
    compared 15 to 2, 15 was larger
    compared 15 to 20, 20 was larger
    compared 20 to 9, 20 was larger
    res0: Int = 20
    

    Boo-yah! Here's how the process worked:

    • reduceLeft started by calling findMax to test the first two elements in the array, andfindMax returned 12 (because 12 is larger than 6).
    • reduceLeft took that result (12), and called findMax(12, 15). 12 was the result of the first comparison, and 15 is the next element in the collection. 15 is larger, so it became the new result.
    • reduceLeft kept taking the result from the function and comparing it to the next element in the collection, until it marched through all the elements in the collection and ended up with the number 20.
    • reduceLeft doesn't know it's finding the largest element in the collection. It just marches through the collection, using the function you provide to (a) compare one element to the next, (b) get the result, then (c) compare that result to the next element in the collection, again using your function to perform the comparison.

    One subtle but important note that we just saw: Your function must return the same data type that's stored in the collection. This is necessary so reduceLeft can compare that result to the next element in the collection.

     

    Working with other collection types

    The collection can be any sequence, including List, Array, Vector, Seq, and more. The type of collection can be anything you need. For instance, determining the longest or shortest string in a collection of strings is also pretty easy:

    scala> val peeps = Vector("al", "hannah", "emily", "christina", "aleka")
    peeps: scala.collection.immutable.Vector[java.lang.String] = Vector(al, hannah, emily, christina, aleka)
    
    // longest
    scala> peeps.reduceLeft((x,y) => if (x.length > y.length) x else y)
    res0: java.lang.String = christina
    
    // shortest
    scala> peeps.reduceLeft((x,y) => if (x.length < y.length) x else y)
    res1: java.lang.String = al
    

    Just take a similar approach with your own data types, and you can use Scala's reduceLeft collection method to handle all sorts of problems like this.

    Summary

    If you were wondering how Scala's reduceLeft collections method worked, I hope these examples have been helpful.

    tags:  

  • 相关阅读:
    [洛谷P2711]小行星
    [洛谷P2264]情书
    [洛谷P2626]斐波那契数列(升级版)
    [洛谷P3195][HNOI2008]玩具装箱TOY
    [洛谷P3254]圆桌问题
    [洛谷P1251]餐巾计划问题
    [洛谷P4015]运输问题
    [洛谷P2604][ZJOI2010]网络扩容
    [洛谷P4001][BJOI2006]狼抓兔子
    [洛谷P3153] [CQOI2009]跳舞
  • 原文地址:https://www.cnblogs.com/ihongyan/p/4768267.html
Copyright © 2011-2022 走看看