说我有
val l1 = List(1,2,3,4)
val l2 = List(True,False,False,True)
我想过滤l1中与l2
中的True元素对应的元素我做了以下事情:
type Predicate[T] = T => Boolean
def filterXbasedOnY[A, B](X: List[A], Y: List[B], p: Predicate[B]): List[A] = {
{
for {i <- 0 until Y.size if p(Y(i))} yield X(i)
}.toList
}
通过调用
工作正常val result = filterXbasedOnY(l1, l2, (b:Boolean) => b)
但这是实现这一目标的最佳方式吗?
答案 0 :(得分:2)
List(1, 2, 3, 4).zip(List(true, false, false, true)).filter(_._2).map(_._1)
正如@ C4stor所建议的那样,如果想要将过滤的使用范围扩大到不同类型,我认为我们可以降低复杂度(我在下面使用toMatch:B来简化,但Predicate仍然可以使用):
def filter[A, B](l1: List[A], l2: List[B], toMatch: B): List[A] = {
l1.zip(l2).filter(_._2 == toMatch).map(_._1)
}
因此,在继续使用List对象的同时,管道将是O(n)。否则,在列表上调用p(Y(i))
n次将是O(n2)。
正如@ C4stor所指出的那样,并且你的解决方案已经是这种情况,它处理的l1比l2短。
filter(List("1", "2", "3"), List("True", "False", "True", "False"), "True") // List(1, 3)
答案 1 :(得分:0)
我不知道这是否是最好的方式,但它至少是一个好方法:
所提议的一个衬里都没有那些理想的属性,所以,对你们有所称,做得好!在我看来,你的解决方案实际上就是建议的一个衬里的准备版本。
顺便说一下,我可以向您推荐codereview stackexchange for codereview style questions吗?
答案 2 :(得分:0)
语法可能使其更具可读性,并且使用filterFunction意味着l2可以是它需要的任何类型。
for( (l1,l2) <- (list1 zip list2) if (filterFunction(l2))) yield l1