Je travaille sur un exercice de calcul de base de stock à partir d'une liste d'achats d'actions sous forme de thruples (ticker, qty, stock_price). Je l'ai fait fonctionner, mais j'aimerais faire la partie calcul de manière plus fonctionnelle. Quelqu'un a-t-il une réponse à cela ?

// input: 
// List(("TSLA", 20, 200),
//      ("TSLA", 20, 100),
//      ("FB", 10, 100)
// output:
// List(("FB", (10, 100)), 
//      ("TSLA", (40, 150))))

def generateBasis(trades: Iterable[(String, Int, Int)]) = { 
  val basises = trades groupBy(_._1) map {
    case (key, pairs) =>
      val quantity = pairs.map(_._2).toList
      val price = pairs.map(_._3).toList
      var totalPrice: Int = 0
      for (i <- quantity.indices) {
        totalPrice += quantity(i) * price(i)
      }
      key -> (quantity.sum, totalPrice / quantity.sum)
    }
  basises
}
1
Scott Manny 28 juin 2016 à 01:40

2 réponses

Meilleure réponse

Cela ressemble à cela pourrait fonctionner pour vous. (mis à jour)

def generateBasis(trades: Iterable[(String, Int, Int)]) =
  trades.groupBy(_._1).mapValues {
    _.foldLeft((0,0)){case ((tq,tp),(_,q,p)) => (tq + q, tp + q * p)}
  }.map{case (k, (q,p)) => (k,q,p/q)}   // turn Map into tuples (triples)
2
jwvh 28 juin 2016 à 07:43

J'ai trouvé la solution ci-dessous. Merci à tous pour leur contribution. J'aimerais savoir si quelqu'un a une solution plus élégante.

// input:
// List(("TSLA", 20, 200),
//      ("TSLA", 10, 100),
//      ("FB", 5, 50)
// output:
// List(("FB", (5, 50)),
//      ("TSLA", (30, 166)))
def generateBasis(trades: Iterable[(String, Int, Int)]) = {

  val groupedTrades = (trades groupBy(_._1)) map {
    case (key, pairs) =>
      key -> (pairs.map(e => (e._2, e._3)))
  } // List((FB,List((5,50))), (TSLA,List((20,200), (10,100))))

  val costBasises = for {groupedTrade <- groupedTrades

    tradeCost = for {tup <- groupedTrade._2 // (qty, cost)
    } yield tup._1 * tup._2 // (trade_qty * trade_cost)

    tradeQuantity = for { tup <- groupedTrade._2
    } yield tup._1 // trade_qty

  } yield (groupedTrade._1, tradeQuantity.sum, tradeCost.sum / tradeQuantity.sum )

  costBasises.toList // List(("FB", (5, 50)),("TSLA", (30, 166)))
}
0
Scott Manny 28 juin 2016 à 07:28