2016-04-02 15 views
4

BitSetを使用するライブラリがあり、ライブラリを使用するにはSet [Int]型のデータを変更する必要があります。Scalaで[Int]を設定するBitSet

.toSeq:_*操作を使用することですが、これはBitSetから[Int]または他の方法に変換する効率的な方法であるとは確信していません。

scala> BitSet(Set(1,2,3).toSeq:_*) 
res55: scala.collection.immutable.BitSet = BitSet(1, 2, 3) 

scala> Set(BitSet(1,2,3).toSeq:_*) 
res56: scala.collection.immutable.Set[Int] = Set(1, 2, 3) 

もっと良い方法がありますか?

+0

'.toSet'または' .seq'はうまくいくはずです – Bergi

+0

[範囲からのスカラビットセットの初期化](http://stackoverflow.com/q/6366976/1048572)は最初の – Bergi

答えて

5

など、ScalaのSet階層は少し奇妙ですが、それは、BitSetがスーパータイプとしてSet[Int]を持っているので、あなたは、単にSet[Int]を期待するメソッドにBitSetを渡すことができるという場合である

これはないかもしれません実際にはSetimmutable.Setscala.collection)ですが、使用しているライブラリがBitSetの直下にあるscala.collectionではなくimmutable.BitSetである可能性があります。これはあなたのサンプルコードではすべてがimmutableにあるケースではありませんが、どのように単純化されているかわかりません。

あなたはSetBitSet両方のimmutableパッケージのバージョンで作業するには十分に幸運なら、BitSetSetへの方向は簡単です:

scala> import scala.collection.immutable.BitSet 
import scala.collection.immutable.BitSet 

scala> val bs = BitSet(0, 100, 200) 
bs: scala.collection.immutable.BitSet = BitSet(0, 100, 200) 

scala> def takesSet(s: Set[Int]): Int = s.size 
takesSet: (s: Set[Int])Int 

scala> takesSet(bs) 
res0: Int = 3 

何とかあなたがscala.collection.BitSet、ちょうど使用を持っていればtoSet:他の方向については

scala> takesSet(scala.collection.BitSet(0, 100, 200).toSet) 
res1: Int = 3 

、お使いのバージョンで結構です。

scala> val s = Set(1, 2, 3) 
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3) 

scala> BitSet(s.toSeq: _*) 
res2: scala.collection.immutable.BitSet = BitSet(1, 2, 3) 

しかし、それはまた、多くの場合、あなたには、いくつかのCanBuildFrom魔法でこの変換を避けることができることは注目に値します:

scala> val bs: BitSet = Set("1", "2", "3").map(_.toInt)(collection.breakOut) 
bs: scala.collection.immutable.BitSet = BitSet(1, 2, 3) 

これは以下と同じ結果生成します。

scala> val bs: BitSet = BitSet(Set("1", "2", "3").map(_.toInt).toSeq: _*) 
bs: scala.collection.immutable.BitSet = BitSet(1, 2, 3) 

しかし、その代わりにBitSetの前に中間セット(およびシーケンス)を構築する場合、collection.breakOutパラメータは、CanBuildFromのインスタンスを使用してマップを実行するようにコンパイラに指示しますBitSetを直接構築するクラス型クラスです。 CanBuildFromインスタンスをこのように明示的に渡すことは、mapの場合だけでなく、flatMap,scanLeft,などで動作し、要素タイプを変更できる他のコレクション操作の場合もあります。BitSetSet[Int]で、あなたが他の1つを変換するために何かをする必要はありません:

0

は、オブジェクト指向を考えて、他の道を行く

 import scala.collection._ 
    val set: Set[Int] = BitSet(1,2,3) 

は困難であり、線形時間がかかります:

 val bs: BitSet = BitSet(set.toStream:_*) 

が、いつでもあなた自身が「アップコンバート」のこの種を必要とする見つける必要性を排除するために改善されるべきであるよりも、時間の99%が、それは、悪いデザインの兆候です:実装の詳細O特にSetは、それを最初に作成するコードに対してのみ重要であり、下流のコードは通常、実装に不可知論的であるべきです。

+0

「99%」はとても楽観的だと思います。 'BitSet'を使って作業する必要がある場合がよくあります。なぜなら、サードパーティAPIやBitSet固有の操作が必要なためです。それを可能にするために通常のセットを 'BitSet'サブタイプに"下げる "。 –

+1

@TravisBrown多分、私は楽観主義者です:)私はちょうどそれが私が作成していないビットセットが必要なユースケースを考えるのは難しいと思っています。私は、人々が本当にそれを必要としているかどうかを考えずに、これらの変換を前後して行うのと同じくらい頻繁ではないと思います。 'Predef'から取得した' Set'は 'scala.collection.immutable.Set'であり、' scala.collection.Set'ではなくIMHOには役立ちません。 – Dima

関連する問題