使用总和返回原始列表中包含的子列表列表

时间:2016-10-20 14:44:55

标签: scala

我有一个零件清单和组合清单。

我有一个汽车零件清单,我想知道零件清单中有多少个组合,并且还得到了重量的总和。

所以我想返回hondaParts中包含的组合列表以及总重量。

  case class Part(id: Int, weight: Int)
case class Combo(parts: List[Part])

val part1 = Part(1, 1)
val part2 = Part(2, 1)
val part3 = Part(3, 2)
val part4 = Part(4, 5)
val part5 = Part(5, 3)
val part6 = Part(6, 8)
val part7 = Part(7, 2)
val part8 = Part(8, 12)
val part9 = Part(8, 1)

val allParts = List(part1, part2, part3, part4, part5, part6, part7, part8, part9)

val combo1 = List(part1, part2)
val combo2 = List(part4, part2)
val combo3 = List(part7, part8, part9)
val combo4 = List(part3)

val combos = List(combo1, combo2, combo3, combo4)

val hondaParts = List(part1, part3, part4, part7, part8, part9)

所以基本上我想要一个hondaParts列表中所有组合的列表。然后我想得到每个组合的重量总和。

我试过了:

combos.forall(hondaParts.contains)

然后才回来布尔。

3 个答案:

答案 0 :(得分:2)

你几乎就在那里 - 你只需要一个额外的filter,这样你就可以检查hondaParts每个组合的每个元素(而不是组合本身):

scala> combos.filter(_.forall(hondaParts.contains))
res0: List[List[Part]] = List(List(Part(7,2), Part(8,12), Part(8,1)), List(Part(3,2)))

这读作"选择每个组合,以便对于每个元素,hondaParts包含该元素"。

作为旁注,combos.forall(hondaParts.contains)是Scala处理相等方式的不幸工件。询问部件列表是否包含部件列表并不是真的有意义,但编译器很乐意让您使用contains执行此操作而不会发出警告。通过将预期的类型参数放在contains

上,您可以使事情更安全一些
scala> combos.forall(hondaParts.contains[Part])
<console>:27: error: type mismatch;
 found   : Part => Boolean
 required: List[Part] => Boolean
       combos.forall(hondaParts.contains[Part])
                                        ^

但修正后的版本编译得很好:

scala> combos.filter(_.forall(hondaParts.contains[Part]))
res1: List[List[Part]] = List(List(Part(7,2), Part(8,12), Part(8,1)), List(Part(3,2)))

答案 1 :(得分:1)

以上答案是正确的。但你得到的是List[List[Part]]。为了获得总和,您可以flattenfold。例如:

val parts = combos.filter(combo => combo.forall(p => hondaParts.contains(p))).flatten
val sum = parts.foldLeft(0)((sum, part) => sum + part.weight)

答案 2 :(得分:0)

我认为您打算使用Combo案例类来实例化combo1,combo2,combo3,combo4。然后解决方案很简单:

case class Part(id: Int, weight: Int)
case class Combo(parts: List[Part])

val part1 = Part(1, 1)
val part2 = Part(2, 1)
val part3 = Part(3, 2)
val part4 = Part(4, 5)
val part5 = Part(5, 3)
val part6 = Part(6, 8)
val part7 = Part(7, 2)
val part8 = Part(8, 12)
val part9 = Part(8, 1)

val allParts = List(part1, part2, part3, part4, part5, part6, part7, part8, part9)

val combo1 = Combo(List(part1, part2))
val combo2 = Combo(List(part4, part2))
val combo3 = Combo(List(part7, part8, part9))
val combo4 = Combo(List(part3))

val combos = List(combo1, combo2, combo3, combo4)

val hondaParts = List(part1, part3, part4, part7, part8, part9)

val filteredCombos = combos.filter(x => x.parts.intersect(hondaParts).size == x.parts.size) 

val comboWeights = filteredCombos.map(x => x.parts.foldLeft(0)((a,b) => a + b.weight))