斯卡拉:对于多种条件的理解

时间:2017-04-05 09:15:19

标签: scala

我有两个列表,val aList = List(2,3,5,15,20)val bList = List (3,5,6)

我需要什么: 如果aList中的元素大于10 ,则在结果中包含该元素。 否则,如果它出现在bList中,则包含元素的平方。 所以,上面例子的答案是List(15,20,9,25)。结果列表可以是任何顺序。

理解是最有效的方法吗?是否有可能在单一的理解 - 收益中实现这一目标?

5 个答案:

答案 0 :(得分:5)

可能是这样的:

aList.flatMap { a =>
  if (a > 10) Option(a) else bList.find(_ == a).map(a => a * a)
}

我们避免不必要的遍历bList

答案 1 :(得分:3)

我是在一次遍历中完成的,为此你不需要for yield,那是flatMap语法糖,但是你'不要在这里映射任何东西。

val res = aList.foldLeft(List.empty[Int]) { (acc, el) =>
  if (el > 10) {
    el :: acc
  } else if (bList.contains(el)) {
    (el * el) :: acc
  } else {
    acc
  }
} 

如果你想让这个稍微漂亮一点,可能会有所偏好,因为有些人可能不会选择写一个if case语句与宗教相符:

val res = aList.foldLeft(List.empty[Int]) { (acc, el) => el match {
    case e if e > 10 => el :: acc
    case e if bList.contains(e) => (e * e) :: acc
    case _ => acc
  }
}

此大O将为O(nlogm),其中n的大小为aListm的大小为bList。在实践中它会好一点,因为你避免对每个大于10的元素进行对数时间查找。除非我的早晨咖啡还没有生效,否则我会错过。

答案 2 :(得分:2)

尝试类似的事情,

aList.filter(_>10) ++ bList.filter(aList.contains(_)).map(x => x*x) 

或者避免bList中的元素超过10个(如果有的话),

aList.filter(_>10) ++ bList.filter(i => i<=10 && aList.contains(i)).map(x => x*x)  

答案 3 :(得分:1)

我认为这里不需要for-comprehension。此外,没有简单的方法可以使用for-compreshension来完成此任务。

val aList = List(2,3,5,15,20)
val bList = List(3,5)

你可以这样做(转换为Set不会保证oder保存并可能导致任意顺序),

val commonEligibleInts = (aList.filter(i => i <= 10).toSet & bList.toSet).toList

val result = aList.filter(i => i > 10) ++ commonEligibleInts.map(i => i * i)

// result: List[Int] = List(15, 20, 9, 25)

您可以使用以下for-comprehension,但这不会为您提供所需的排序(此处的订单将与aList中的订单相同),

val bListSet = bList.toSet

val result2 = for {
  i <- aList
  r <- if (i > 10) Some(i) else if (bListSet.contains(i)) Some(i*i) else None
} yield r

// result2: List[Int] = List(9, 25, 15, 20)

或者,您可以采用这种方法,这种方法比上述方法更有效,并且还会导致所需的排序,

val bListSet = bList.toSet

val result3 = aList.flatMap({
  case i if i > 10 => Some(i)
  case i if bListSet.contains(i) => Some(i*i)
  case _ => None
})

// result3: List[Int] = List(15, 20, 9, 25)

答案 4 :(得分:1)

我为猫皮肤的替代方案

val (x,y) = aList.partition( _ >10)
val r = x++(y intersect bList).map(e=>e*e)
// List(15, 20, 9, 25)