Фильтр Scala по двум условиям

Я хотел бы отфильтровать свой набор данных сразу по двум условиям.

Является ли это возможным?

Я хочу что-то вроде этого:

mystuff = mystuff.filter(_.isX && _.name == "xyz")

person richsoni    schedule 20.06.2012    source источник


Ответы (3)


Используя немного менее краткий синтаксис лямбда:

mystuff = mystuff.filter(x => (x.isX && x.name == "xyz"))

Вы можете найти более подробную информацию о синтаксисе анонимных функций Scala здесь .

person Alex Wilson    schedule 20.06.2012
comment
это устраняет накладные расходы на производительность? Я имею в виду, что в конце запроса это правильно выражено? - person zinking; 13.04.2014

Хотя может быть некоторое влияние на производительность в зависимости от того, что такое «myStuff», вы всегда можете отфильтровать дважды

mystuff = mystuff.filter(_.isX).filter(_.name == "xyz")
person Dave Griffith    schedule 20.06.2012
comment
Это приводит к двойному зацикливанию всего списка. - person Kamil Lelonek; 30.05.2014
comment
@squixy просто к вашему сведению, это не так. filter создает новую проекцию (или представление) коллекции таким образом, что когда элемент запрашивается во время итерации (т. е. map, fold и т. д.), применяются функции filter, чтобы увидеть, возвращается ли элемент - person ThaDon; 29.05.2016
comment
@ThaDon неверно - это зависит от типа коллекции, но наиболее распространенный (Array, List, Vector...) создаст промежуточную коллекцию - person AlexFoxGill; 21.06.2018

Если вам нужно часто фильтровать несколько предикатов, вы можете определить способ их объединения:

case class And[A]( p1: A=>Boolean, p2: A=>Boolean ) extends (A=>Boolean) {
  def apply( a: A ) = p1(a) && p2(a)
}

Вот как использовать его, чтобы сохранить только нечетные числа больше 10:

scala> (0 until 20) filter And( _ > 10, _ % 2 == 1 )
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 13, 15, 17, 19)

Таким же образом легко написать комбинаторы Or и Not.

person paradigmatic    schedule 20.06.2012
comment
Есть ли у этого метода преимущество перед использованием лямбда-функции mystuff.filter( each => each.isX && each.name.equals("xyz"))? - person ForeverLearner; 06.02.2020