2017-10-01 5 views
1

私は現在、これをやっている:コレクションの個別フィールドを効率的に数えるにはどうすればよいですか?

val count = sightings.map(_.shape).distinct.length 

しかし、mapは、私の場合にはdistinctが生成するものよりも大きな倍のベクトルの何千ものである仲介コレクションを作成します。

この中間ステップをバイパスして、別個のシェイプのセットを取得するにはどうすればよいですか?それとも、もっと良いのは、別個の形の数です。

答えて

3

あなたは中間コレクションを作成しないようにイテレータを使用して、明確なものを得るためにSetで図形を計上することができます

また
val count = sightings.iterator.map(_.shape).toSet.size 

、あなたはなしSet内の項目を計上しcollection.breakOutを使用することができます中間コレクションを作成する(別の答えはbreakOutを使用して提案したが、別の方法で):他の回答から離れて

val distinctShapes: Set[Shape] = sightings.map(_.shape)(collection.breakOut) 
val count = distinctShapes.size 
+0

"Iterator [String]のメンバーではない値が得られました" – Ruby

+0

意味があります。私は間違いを修正するために答えを編集します。解決策は、イテレータを 'Set'に変えてから、そのサイズを得ることです。 – stefanobaghino

3

1つの方法は、重複を削除してから結果を数える方法です。

sightings.foldLeft(Set[Shape]()){case (ss,sight) => ss + sight.shape}.size 

中間のSetの形状は、今までに出会ったすべての異なる形状と同じくらい大きなものです。

2

、あなたのプロのための厳密解があります傷み。

Breakoutは、あなたが探しているキーです。

使用例:中間コレクションを作成breakOut防止を使用して、ここ

import scala.collection.breakOut 
val count = sightings.map(_.shape)(breakOut).distinct.length 

、。

詳細については、documentationをお読みください。

+0

'breakOut'はあるコレクションから別のコレクションに移動する必要があるときに、中間コレクションを作成しないようにすることができます(中間コレクションを持たないでペアからマップに移動する例)。この場合、必要なのは、 'map'と' distinct'の間の怠惰な操作です。しかし、あなたの例は、 'Set'を使うと次のように活用できます:' val distinctShapes:Set [Shape] = sightings.map(_。shape)(collection.breakOut); val count = distinctShapes.size' – stefanobaghino

+0

私はあなたのことを理解できないのではないかと心配しています。あなたは詳細を教えていただけますか? – fcat

+0

'breakOut'は(いくつかの操作の中で)' map'を実行している間に得られたコレクションを変更する方法として機能します。 'distinct'はあなたがマップされた後に発生するので、あなたの例で中間コレクションの作成をスキップすることはできません。しかし、 'Set'をターゲットコレクションとして使用すると、' Set'が構築されている間に別のアイテムを選択して実行し、中間コレクションの構築を保存します。 – stefanobaghino

関連する問題