11

私は Scala 2.9.2 を使用しており、いくつかの条件に基づいてリストを作成したいと考えています。

cond は、述語 p と型 T の値 (この場合は t3) を取る関数です。

t1 :: t2 :: cond( p, t3 ) :: t4

私が望む動作は次のとおりです。p が true の場合、次のようになります。

List[T]( t1, t2, t3, t4 )

p が false と評価された場合、次のようになります。

List[T]( t1, t2, t4 )

私はおそらくこれを完全に間違った方法で考えていますが、エレガントな解決策を考え出すのに苦労しています. オプションをどこにでも含めてからフィルター処理することもできますが、それではコードが読みにくくなります。

def cond[T]( p : => Boolean, v : T ) : Option[T] =
{
    p match
    {
        case true => Some( v )
        case false => None
    }
}

これにより、次のことが可能になります。

scala> ( Some( 1 ) :: Some( 2 ) :: cond( true, 3 ) :: Some( 4 ) :: Nil ).flatten
res4: List[Int] = List(1, 2, 3, 4)

scala> ( Some( 1 ) :: Some( 2 ) :: cond( false, 3 ) :: Some( 4 ) :: Nil ).flatten
res5: List[Int] = List(1, 2, 4)

ただし、これは最も洗練されたソリューションではありません。ユーザーは、無条件の要素をすべて Some( ) でラップする必要があり、最後にフラット化を行うことを忘れないでください。よりエレガントなソリューションを考えられる人はいますか?

4

5 に答える 5

10

リストを生成するのはどうですか?

@inline def cond[T]( p : => Boolean, v : T ) : List[T] = if(p) v::Nil else Nil

そして、それらを次のように使用します。

List(1,2,3) ++ cond(false, 3 ) ++ List(4)
于 2013-03-22T11:06:14.720 に答える
5

条件で新しいリストを作成してフィルタリングしてみてください。

List[T](t1, t2, t3, t4).filter(p)
于 2013-03-22T11:07:40.663 に答える
1

オプションとして、Scala.collection.mutable パッケージで ListBuffer を使用するように切り替えることを検討できます。

val listBuffer = new ListBuffer[<item_type>]
if(<item1_cond>) listBuffer += <item1>
if(<item2_cond>) listBuffer += <item2>

これはまだ可変コレクションを指す val (不変参照) であることに注意してください。

于 2018-07-05T03:09:04.013 に答える
0

適切な述語を選択するためにインデックスを知る必要がある場合は、結果からインデックスを削除し、述語の選択とアプリケーションをガードでエンコードできるようにする代わりにzipWithIndex、インデックスと値をペアにしてから使用することができます。例えば:collectfilter

List(1, 4, 9, 16, 25).zipWithIndex.collect { case (n, i) if (n + i) % 3 <= 1 => n }
res0: List[Int] = List(1, 16)
于 2013-03-22T14:06:23.023 に答える