Scala:配列に要素を追加する最良の方法は何ですか?


111

私がArray[Int]好きだと言う

val array = Array( 1, 2, 3 )

4次の例のように、配列に要素、たとえばvalueを追加したいと思います。

val array2 = array + 4     // will not compile

もちろんSystem.arraycopy()自分で使用してこれを行うこともできますが、これにはScalaライブラリー関数が必要です。ポインタをありがとう!

ノート:

  1. 次の行のように、要素の別の配列を追加できることは承知していますが、それはあまりにも回りすぎに見えます。

    val array2b = array ++ Array( 4 )     // this works
  2. ListとArrayの長所と短所を認識しており、ここでは特にArrayの拡張に関心があるさまざまな理由があります。

編集1

:+演算子メソッドを指している答えをありがとう。これは私が探していたものです。残念ながら、これは、カスタムのappend()メソッドの実装よりもかなり遅く、arraycopy約2〜3倍遅くなります。の実装を見ると、SeqLike[]ビルダーが作成され、配列が追加され、ビルダーを介して追加が行われ、ビルダーがレンダリングされます。配列の適切な実装ではありません。2つの方法を比較する簡単なベンチマークを行い、10サイクルのうち最も速い時間を調べました。あるクラスの8要素の配列インスタンスに単一項目の追加を1,000万回繰り返すと、を使用する単純なメソッドでFoo3.1秒:+、1.7秒かかりappend()ます。System.arraycopy();Longの8要素の配列で1000万の単一項目の追加の繰り返しを行う:+と、単純なappend()方法では2.1秒、0.78秒かかります。これをカスタム実装のライブラリで修正できなかったのではないArrayでしょうか。

編集2

それが価値があるもののために、私はチケットを提出しました:https//issues.scala-lang.org/browse/SI-5017


11
なぜArrayBufferその+=方法を使わないのですか?これにより、償却後のO(1)が追加されます。
Fred Foo

1
scalaでは、次のSystem.arraycopy(...)ものに置き換えられますArray.copy(...)
パラダイム的な

1
ListとArrayの長所と短所を知っていますが、1,000万回の追加のベンチマーク結果に驚いていますか?
ユーザー不明

もう一度使ってベンチマークを実行することができArrayBufferた後、変換された最後のアレイに追加する(としますかtoArray)?
パラダイム的

@paradigmatic:もちろん、ベンチマークは同じ配列への1,000万回の追加ではなく、8要素の配列への単一アイテムの追加の1,000万回の繰り返しでした。それに応じて質問を更新しました。
Gregor Scheidt、2011

回答:


204

を使用:+して、要素を配列に追加し、要素の+:先頭に追加できます。

0 +: array :+ 4

生成する必要があります:

res3: Array[Int] = Array(0, 1, 2, 3, 4)

これは、の他の実装と同じですSeq


3
これは、他のscalaの順序付けられたコレクションと同じです。たとえば、セットでは機能しません(プリペンドとアペンドはセットに対して何も意味しないため)。
ニコラ

@Nicolas任意のシーケンス。順序付けはソートされたことを意味ます。
ダニエルC.ソブラル2011

@ダニエルはい、私がコメントを書いたとき、私には小さなメモリホールしかありませんでした。「シーケンス」という明白な単語を見つけられませんでした
ニコラス

@tenshiこれらすべての演算子は新しい配列を作成しますか?はい、あります(から:+コード)Array.copy(repr, 0, result, 0, repr.length)
Timofey

59
val array2 = array :+ 4
//Array(1, 2, 3, 4)

作品も「逆転」:

val array2 = 4 +: array
Array(4, 1, 2, 3)

「インプレース」バージョンもあります。

var array = Array( 1, 2, 3 )
array +:= 4
//Array(4, 1, 2, 3)
array :+= 0
//Array(4, 1, 2, 3, 0)

11
なぜArrayBufferと同じように、Arrayコレクションがappend()メソッドを使用しないのかと思います。new演算子は、私の意見では、それはそれ以上は調整され、使用より統一:+ / +:
DjVuの

8

最も簡単な方法は次のとおりです。

Array(1, 2, 3) :+ 4

実際、配列は暗黙のうちに変換できます。 WrappedArray


その場合、それはより優先度の高いArrayOpsへの変換になります
Didier Dupont
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.