"С" оператором, эквивалентным Scala? - PullRequest
14 голосов
/ 14 июля 2010

Бесполезно размышляю от ученика Scala, но ... в своих работах я написал следующее:

( n.child.size > 0 ) && ( n.child.filter( ! _.isInstanceOf[Text] ).size == 0 )

('n' - это scala.xml.Node, но это не важноНе является особой логикой.)

Дважды вызвать child () не так уж хорошо, поэтому я собирался изменить это:

val list = n.child
( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 )

Но, учитывая, сколько я пришелЯ очень признателен за возможность применения filter (), map () и т. д. без необходимости объявления промежуточных переменных.Это так ... так ... так ява!: p

Увы, копаясь в SO и Google и ScalaDocs (особенно Any и AnyRef) и The Book не нашел ничего подходящего.Возможно, я надеялся на что-то вроде:

n.child{ list => ( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 ) }

или даже

n.child.with{ list => ... }

Существует ли что-то подобное?Или я просто попадаю в пыл с переменным бездействием?

Ответы [ 6 ]

21 голосов
/ 14 июля 2010
{
    import n.child._
    ( size > 0 ) && ( filter( ! _.isInstanceOf[Text] ).size == 0 )
}
18 голосов
/ 14 июля 2010

«с» - это, конечно, зарезервированное слово в Scala, поэтому давайте назовем его «let» из аналогичной формы связывания в Lisp и Haskell.Оказывается, «let» - это просто обратный способ написания приложения-функции.

def let[A,B](param:A)(body: A=>B):B = body(param)

let(n.child){list=> ...}

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

8 голосов
/ 14 июля 2010
class Tap[A](underlying:A){
   def tap[B](func: A=>B) = func(underlying)
}

implicit def anyToTap[A](underlying:A)=new Tap(underlying)

n.child.tap{x =>
   ( x.size > 0 ) &&
   ( x.filter( ! _.isInstanceOf[Text] ).size == 0 )
}
4 голосов
/ 14 июля 2010

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

val n = getNodeByMagic()
val passesTest = {
    val child = n.child
    child.length == 0 && !child.filter(_.isInstanceOf[Text]).isEmpty
}
// child is not defined outside of the block
1 голос
/ 08 октября 2018

Начиная с Scala 2.13, стандартная библиотека теперь предоставляет метод операции связывания pipe, точно соответствующий этой потребности:

import scala.util.chaining._

n.child.pipe(list => list.size > 0 && list.filterNot(_.isInstanceOf[Text]).size == 0)

Значение n.child «передано» интересующей функции.

1 голос
/ 31 марта 2016

Вы можете использовать match для этой цели.

n.child match {
case list => ( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...