Есть ли более хороший способ выполнить следующую обработку if / else в Scala? - PullRequest
0 голосов
/ 04 октября 2011

У меня есть система, управляемая событиями, которая реагирует на сделки следующим образом

def onTrade {

    if (price > threshold) {
        processReject()
        return
    } 

    if (volume > threshold) {
        processReject()
        return
    } 
    .
    .
    .
}

Я думал, что могу улучшить синтаксически, определив внутренний метод

def onTrade {

    def filterRemove = (filter: Boolean) => {
        if (filter) {
            processReject()
        }
        filter
    }

    val filters = List(
        filterRemove(price > threshold),
        filterRemove(volume > threshold),...
    )

    if (filters.filter(x => x == true).size > 0) return

}

Синтаксис особенно чистпо мере увеличения количества фильтров.Единственная проблема, с которой я столкнулся, заключается в том, что код тратит ненужные тактовые циклы, проходя каждый отдельный тест, а не возвращаясь при первом сбое.Это как-то обойти это?Например, выход из onTrade, как только filterRemove вернет false.Если есть более выразительный способ сделать это, я бы тоже хотел это знать.

Ответы [ 5 ]

7 голосов
/ 04 октября 2011

Вы можете, например, вести список условий для отказа. Затем вы можете вызывать их последовательно с exists. Как только условие равно false, итерация заканчивается.

Вот небольшой пример:

val conditions: List[() => Boolean] =
  List(
    () => price > threshold1,
    () => volume > threshold2
  )

def checkAndReject() = {
  val filter = conditions.exists( _() )
  if( filter ) processReject()
  filter
}
6 голосов
/ 04 октября 2011

Если вы просто собираетесь писать условия местами, а не просто использовать или? Правильно полужесткий

if (
  price > threshold1
  || volume > threshold2
  || ...
) {
   processReject()
   return
}
... proceed
4 голосов
/ 04 октября 2011

Проблема в том, что у вас есть список логических значений - все они уже обработаны.Вы должны отложить это.Например:

def onTrade {

    // now filterRemove returns Function0[Boolean]
    // also, filter is passed by-name, so it isn't 
    // processed until you call the Function0
    def filterRemove(filter: => Boolean) = () => {
        if (filter) {
            processReject()
            true
        } else false
    }

    // This won't process anything, just accumulate Function0's
    val filters = List(
        filterRemove(price > threshold),
        filterRemove(volume > threshold),...
    )

    // And we use "exists", which returns on the first true value
    if (filters.exists(x => x)) return

}
3 голосов
/ 04 октября 2011

Это не очень функциональный или идиоматический стиль, но может представлять интерес:

def onTrade {
    val reject = () => {
        processReject()
        return
    }

    // ...

    if (price > threshold) reject()

    // ...

    if (volume > threshold) reject()

    // ...

}
0 голосов
/ 05 октября 2011

Если нет слишком большого количества порогов для проверки, я бы сделал следующее:

def process(price:Int, volume:Int) = (price, volume) match {
   case (x:Int, y:Int) if x > threshold1 || y > threshold2 => println ("reject")
   case _ =>
}

проверка следующим образом:

def threshold1 = 10
def threshold2:Int = throw new Exception // redefine to throw exception
def process(price:Int, volume:Int) = (price, volume) match {
   case (x:Int, y:Int) if x > threshold1 || y > threshold2 => println ("reject")
   case _ =>
}

process(12, 22)
process(5, 22) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...