使用 Futures 通过在 Scala 中链接来计算聚合
Using Futures to calculate aggregate by chaining in scala
嗨,我是 scala 的新手,我正在处理示例
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Test {
def main(args: Array[String]): Unit = {
case class User(id: Int)
case class Subject(id: Int, includeForTotal: Boolean)
case class UserScore(userId: Int, score: Int)
def getUsers(classID: Int): Future[Seq[User]] = {
Future.successful(Seq(User(id = 1), User(id = 2)))
}
def getSubjects(userID: Int): Future[Seq[Subject]] = {
Future.successful(Seq(Subject(id = 1, true), Subject(id = 2, false)))
}
def getScore(subjectID: Int, userId: Int): Future[Int] = {
case class ScoreByUser(userId: Int, subjectID: Int, score: Int)
val scoresStore = Seq(
ScoreByUser(userId = 1, subjectID = 1, 60),
ScoreByUser(userId = 1, subjectID = 2, 70),
ScoreByUser(userId = 2, subjectID = 1, 75),
ScoreByUser(userId = 2, subjectID = 2, 90))
val score = scoresStore.find { x =>
x.subjectID == subjectID && x.userId == userId
}.map(_.score)
Future.successful(score.getOrElse(0))
}
def getBonusScore(userId: Int): Future[Int] = {
if (userId == 1) {
Future.successful(30)
}
else {
Future.successful(20)
}
}
def getTotalScore(classID: Int): Future[Seq[UserScore]] = {
// get users in class
// for each user get subjects, filter subjects includeForTotal
// sum scores for each user along with extra bonus score and return Future
}
import scala.concurrent.duration._
val classId1Score = Await.result(getTotalScore(1), 5 seconds)
println("class1: " + classId1Score)
val classId2Score = Await.result(getTotalScore(1), 5 seconds)
println("class2: " + classId2Score)
}
}
谁能帮我找到 getUsersTotalScoresFrom
给定 class id
的每个用户,其中 includeForTotal
为真
你可以保留 flatMapping 以备将来使用或用于理解。此外,您的 getScore
函数是错误的,因为 score.getOrElse(0)
将 return Any
.
例如,
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Test {
def main(args: Array[String]): Unit = {
case class User(id: Int)
case class Subject(id: Int, includeForTotal: Boolean)
case class UserScore(userId: Int, score: Int)
def getUsers(classID: Int): Future[Seq[User]] = {
Future.successful(Seq(User(id = 1), User(id = 2)))
}
def getSubjects(userID: Int): Future[Seq[Subject]] = {
Future.successful(Seq(Subject(id = 1, true), Subject(id = 2, false)))
}
def getScore(subjectID: Int, userId: Int): Future[Int] = {
case class ScoreByUser(userId: Int, subjectID: Int, score: Int)
val scoresStore = Seq(
ScoreByUser(userId = 1, subjectID = 1, 60),
ScoreByUser(userId = 1, subjectID = 2, 70),
ScoreByUser(userId = 2, subjectID = 1, 75),
ScoreByUser(userId = 2, subjectID = 2, 90))
val score = scoresStore.find { x =>
x.subjectID == subjectID && x.userId == userId
}.map(_.score)
Future.successful(score.getOrElse(0))
}
def getTotalScore(classID: Int): Future[Seq[UserScore]] = {
getUsers(classID).flatMap { users =>
Future.traverse(users) { user =>
getSubjects(user.id).flatMap { userSubjects =>
Future.traverse(userSubjects) { subject =>
if (subject.includeForTotal) getScore(subject.id, user.id)
else Future.successful(0)
}
}.map(_.sum).map(score => UserScore(user.id, score))
}
}
}
import scala.concurrent.duration._
val classId1Score = Await.result(getTotalScore(1), 5 seconds)
println("class1: " + classId1Score)
val classId2Score = Await.result(getTotalScore(1), 5 seconds)
println("class2: " + classId2Score)
}
}
产出
class1: List(UserScore(1,60), UserScore(2,75))
class2: List(UserScore(1,60), UserScore(2,75))
嗨,我是 scala 的新手,我正在处理示例
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Test {
def main(args: Array[String]): Unit = {
case class User(id: Int)
case class Subject(id: Int, includeForTotal: Boolean)
case class UserScore(userId: Int, score: Int)
def getUsers(classID: Int): Future[Seq[User]] = {
Future.successful(Seq(User(id = 1), User(id = 2)))
}
def getSubjects(userID: Int): Future[Seq[Subject]] = {
Future.successful(Seq(Subject(id = 1, true), Subject(id = 2, false)))
}
def getScore(subjectID: Int, userId: Int): Future[Int] = {
case class ScoreByUser(userId: Int, subjectID: Int, score: Int)
val scoresStore = Seq(
ScoreByUser(userId = 1, subjectID = 1, 60),
ScoreByUser(userId = 1, subjectID = 2, 70),
ScoreByUser(userId = 2, subjectID = 1, 75),
ScoreByUser(userId = 2, subjectID = 2, 90))
val score = scoresStore.find { x =>
x.subjectID == subjectID && x.userId == userId
}.map(_.score)
Future.successful(score.getOrElse(0))
}
def getBonusScore(userId: Int): Future[Int] = {
if (userId == 1) {
Future.successful(30)
}
else {
Future.successful(20)
}
}
def getTotalScore(classID: Int): Future[Seq[UserScore]] = {
// get users in class
// for each user get subjects, filter subjects includeForTotal
// sum scores for each user along with extra bonus score and return Future
}
import scala.concurrent.duration._
val classId1Score = Await.result(getTotalScore(1), 5 seconds)
println("class1: " + classId1Score)
val classId2Score = Await.result(getTotalScore(1), 5 seconds)
println("class2: " + classId2Score)
}
}
谁能帮我找到 getUsersTotalScoresFrom
给定 class id
的每个用户,其中 includeForTotal
为真
你可以保留 flatMapping 以备将来使用或用于理解。此外,您的 getScore
函数是错误的,因为 score.getOrElse(0)
将 return Any
.
例如,
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Test {
def main(args: Array[String]): Unit = {
case class User(id: Int)
case class Subject(id: Int, includeForTotal: Boolean)
case class UserScore(userId: Int, score: Int)
def getUsers(classID: Int): Future[Seq[User]] = {
Future.successful(Seq(User(id = 1), User(id = 2)))
}
def getSubjects(userID: Int): Future[Seq[Subject]] = {
Future.successful(Seq(Subject(id = 1, true), Subject(id = 2, false)))
}
def getScore(subjectID: Int, userId: Int): Future[Int] = {
case class ScoreByUser(userId: Int, subjectID: Int, score: Int)
val scoresStore = Seq(
ScoreByUser(userId = 1, subjectID = 1, 60),
ScoreByUser(userId = 1, subjectID = 2, 70),
ScoreByUser(userId = 2, subjectID = 1, 75),
ScoreByUser(userId = 2, subjectID = 2, 90))
val score = scoresStore.find { x =>
x.subjectID == subjectID && x.userId == userId
}.map(_.score)
Future.successful(score.getOrElse(0))
}
def getTotalScore(classID: Int): Future[Seq[UserScore]] = {
getUsers(classID).flatMap { users =>
Future.traverse(users) { user =>
getSubjects(user.id).flatMap { userSubjects =>
Future.traverse(userSubjects) { subject =>
if (subject.includeForTotal) getScore(subject.id, user.id)
else Future.successful(0)
}
}.map(_.sum).map(score => UserScore(user.id, score))
}
}
}
import scala.concurrent.duration._
val classId1Score = Await.result(getTotalScore(1), 5 seconds)
println("class1: " + classId1Score)
val classId2Score = Await.result(getTotalScore(1), 5 seconds)
println("class2: " + classId2Score)
}
}
产出
class1: List(UserScore(1,60), UserScore(2,75))
class2: List(UserScore(1,60), UserScore(2,75))