Скала: який найкращий спосіб додати елемент до масиву?


111

Скажіть, мені Array[Int]подобається

val array = Array( 1, 2, 3 )

Тепер я хотів би додати елемент до масиву, сказати значення 4, як у наступному прикладі:

val array2 = array + 4     // will not compile

Я, звичайно, можу скористатися System.arraycopy() і робити це самостійно, але для цього повинна бути функція бібліотеки Scala, яку я просто не міг знайти. Дякуємо за будь-які покажчики!

Примітки:

  1. Я усвідомлюю, що можу додати ще один масив елементів, як у наступному рядку, але це здається занадто круглим:

    val array2b = array ++ Array( 4 )     // this works
  2. Мені відомо про переваги та недоліки списку проти масиву, і ось я з різних причин конкретно зацікавлений у розширенні масиву.

Редагуйте 1

Дякуємо за відповіді, що вказують на :+метод оператора. Це те, що я шукав. На жаль, це набагато повільніше, ніж використання методу користувальницької додавання (), використовуючи arraycopy- приблизно в два-три рази повільніше. Дивлячись на реалізацію в SeqLike[], створюється builder, потім до нього додається масив, потім додавання робиться через builder, потім надається builder. Недобра реалізація для масивів. Я зробив швидкий показник порівняння двох методів, дивлячись на найшвидший час з десяти циклів. Здійснення 10 мільйонів повторів одного елемента, доданих до 8-елементного екземпляра масиву деякого класу, Fooзаймає 3,1 секунди :+та 1,7 секунди простим append()методом, який використовуєSystem.arraycopy(); роблячи повторення додавання 10 мільйонів одноелементів на 8-елементних масивах Long, що займає 2,1 секунди, :+а прості - 0,78 сек.append()метод. Цікаво, що це не вдалося виправити в бібліотеці із спеціальною реалізацією дляArray ?

Редагуйте 2

На що це варто, я подав квиток: https://isissue.scala-lang.org/browse/SI-5017


11
Чому б не використовувати ArrayBufferі його +=метод? Це дасть вам амортизований додаток O (1).
Фред Фоо

1
У масштабі System.arraycopy(...)замінюєтьсяArray.copy(...)
парадигматичний

1
Вам відомо про переваги та недоліки списку проти масиву, але ви здивовані результатами порівняльних показників у 10 мільйонів додатків?
користувач невідомий

Чи можете ви знову запустити свій орієнтир, використовуючи ArrayBufferперетворений після останнього додавання до масиву (з toArray)?
парадигматичний

@paradigmatic: Тест звичайно був не 10 мільйонів додань до одного масиву, а 10 мільйонів повторів одного елемента, що додаються до 8-елементного масиву. Я відповідно оновив питання.
Грегор Шейдт

Відповіді:


204

Ви можете використовувати :+для додавання елемента до масиву та додати +:його:

0 +: array :+ 4

повинен виробляти:

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

Це те саме, що і з будь-якою іншою реалізацією Seq.


3
Це те ж саме, що і для будь-якої іншої замовленої колекції Scala , вона не працює з набором, наприклад (як додавання та додавання нічого не означає для набору).
Ніколя

@Nicolas Будь-яка послідовність. Упорядкований передбачає сортування .
Даніель К. Собрал

@Daniel Так, у мене просто невеликий отвір пам’яті, коли я написав коментар, і я не знайшов очевидного слова «послідовність»
Nicolas

@tenshi чи всі ці оператори створили новий масив? Так, так (від: + код)Array.copy(repr, 0, result, 0, repr.length)
Тимофей

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
Мені просто цікаво, чому колекція Array не використовує метод append (), як ArrayBuffer. На мою думку, це скоріше Координація та уніфікація, ніж використання нового оператора: + / +:
Djvu

8

Найпростішим може бути:

Array(1, 2, 3) :+ 4

Насправді, масив може бути безслідно перетворений в a WrappedArray


У такому випадку це буде перетворення з вищим пріоритетом у ArrayOps
Didier Dupont,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.