2017-06-15 4 views
1

私は以下のクラスがあります。スカラ:期間の合計によってソート・リスト

("P1", List(Task("T1", 15 minute), Task("T2", 10 minute))) 

("P2", List(Task("T3", 10 minute))) 

("P3", List(Task("T1", 15 minute))) 

は、今私はリストを注文したい。そして、

Task(id: String, time: Duration) 

Product(id: String, tasks: List[Task]) 

、私は次の要素を持つリストlist: List[Product]を持っているが各製品が生産するのに必要な時間の合計で割ったものです。この場合、私は、出力はそうのようになりたかった:

("P2", List(Task("T3", 10 minute))) // 10 min total 

("P3", List(Task("T1", 15 minute))) // 15 min total 

("P1", List(Task("T1", 15 minute), Task("T2", 10 minute))) // 25 min total 

私はこのような何かをやって思ったが、それは動作しません:

list.sortBy(p => p.tasks.map(t => t.time)) 

は、私はこれを行うことができますどのようにあなたたちを知っています? nanos値に時間を変換する時間によって

答えて

1

:これはSemigroup[Duration]を宣言する必要だろうが

def totalTime(tasks: NonEmptyList[Task]) 
    = tasks.map(_.time).foldl1(_ plus _) 

実際には、あなたは、内蔵のscalazでfoldMap)をマップ-削減の利点を取ることができますここでリストをソートする一つの方法です:

list.sortBy(
    p => p.tasks.map(t => t.time.toMillis).sum 
) 
res1: List[Product] = List(
    Product(P2,List(Task(T3,10 minutes))), 
    Product(P3,List(Task(T1,15 minutes))), 
    Product(P1,List(Task(T1,15 minutes), Task(T2,10 minutes))) 
) 

ソートされたリストを確認するには:

list.map(
    p => (p.id, p.tasks.map(t => t.time.toMinutes).sum) 
) 
res2: List[(String, Long)] = List((P1,25), (P2,10), (P3,15) 
1

ソート

scala> list.sortBy(p => p.tasks.map(_.time.toNanos).sum) 
result: List[Product] = List(Product(P1,List(Task(T1,15 minutes), Task(T2,10 minutes)))) 
2

あなたは(あなたが内側のリストで期間を加算していない)非常に接近している:それはより多くの意味を作る可能性があることを

list.sortBy(p => p.tasks.foldLeft(Duration.ZERO)(_ plus _.time)) 

注意そして、あなたが書くことができますので

def totalTime(tasks: Seq[Task]): Duration 
    = tasks.foldLeft(Duration.ZERO)(_ plus _.time) 

:ここに別の関数を書くこと

list.sortBy(p => totalTime(p.tasks)) 

NOTES:

あなたが安全にそうするべきであるがあなたはまた、reduceを使用することができ(すなわち、あなたがあなたの内側のリストが空にすることはできません確信している場合

def totalTime(tasks: Seq[Task]) 
    = tasks.map(_.time).reduceLeftOption(_ plus _).getOrElse(Duration.ZERO) 

より高度な

)あなたのリストが非空であると仮定しないで、あなたは、このようなscalazとして、これを強制データ型を使用する必要がありますNonEmptyList。その後、使用することができます

implicit val DurationSemigroup: Semigroup[Duration] 
    = Semigroup.instance(_ plus _) 

def totalTime(tasks: NonEmptyList[Task]) = tasks.foldMap1(_.time)) 
関連する問題