2017-06-15 8 views
1

Scalaの要素コレクションと、最初のコレクションと同じサイズの別のブール値コレクションがあるとしましょう(2番目のコレクションはRamer-Douglas-Peucker algorithmの結果です)。コレクションからすべてのインデックスを削除する

ここでは、中間コレクションを作成せずに、同じインデックスの2番目のコレクションが同じインデックスの2番目のコレクションである1回目のコレクションからすべてのアイテムを削除します。私はそれを行うことができる任意のScalaコレクションで組み込みのメソッドを見つけることができませんでした。もちろん私は自分自身を書くことができますが、Scalaのコレクションはまだ一つではありません。私はそれを逃していますか?

例:

List(1, 2, 3).removeWhere(List(false, true, false)) shouldEqual List(2) 
// removeWhere is an imaginary name for the method I'm looking for 

答えて

1

I "には、シングルパス" これはとしての資格かどうかわからないが、あなたは何ができる:

val list1 = List(1, 2, 3) 
val list2 = List(false, true, false) 
val filtered = list1.filter(elem => list2(list1.indexOf(elem))) 

list1が重複している場合は、上記不十分であり、要素。おそらくあなたの「シングルパス」の要件に違反してそれを行うには

もう一つの方法は、次のとおりです。

val filtered = list1.zip(list2).filter(_._2).map(_._1) 
+1

それは二次だが、まだ例のように、短いリストのために働くだろう。 'zip'の解は線形です(さらに短くなります)。 – 9000

+0

ジップバージョンは間違いなく優れています。 '' 'list1.indexOf'''はリニア自体であることを忘れないでください。 2回のパスはOKです。 –

2

viewプロセス要素を一つずつ。

scala> val xs = List(1,2,3).view.zip(List(true,false,true)).collect{case (x, true) => x} 
xs: scala.collection.SeqView[Int,Seq[_]] = SeqViewZFM(...) 

scala> xs.head 
res0: Int = 1 

scala> xs.tail 
res1: scala.collection.SeqView[Int,Seq[_]] = SeqViewZFMS(...) 
1

私は退屈だったとマニュアルのバージョンを書きました:

def removeWhere_(l1 : List[Int], l2 : List[Boolean], acc : List[Int] => List[Int]) : List[Int] = { 
    (l1, l2) match { 
     case (x::xs, y::ys) if y => removeWhere_(xs,ys, f => acc(x :: f)) 
     case (x::xs, y::ys)  => removeWhere_(xs,ys, f => acc(f)) 
     case _ => acc(List()) 
    } 
    } 

def removeWhere(l1 : List[Int], l2 : List[Boolean]) = removeWhere_(l1, l2, x => x) 

あなたは末尾呼び出しの最適化を可能にするために、すべてのファンクタを作るから失うが、それは一つだけトラバーサルだどのくらいわかりません。

0

あなたは、その怠惰な対応、StreamListを変換し、使用することができますzipfilter

List(1, 2, 3).toStream.zip(List(false, true, false)).filter(_._2).map(_._1).toList 
関連する問題