स्काला: किसी ऐरे में किसी तत्व को जोड़ने का सबसे अच्छा तरीका क्या है?


111

कहो मेरे पास एक Array[Int]पसंद है

val array = Array( 1, 2, 3 )

अब मैं एक तत्व को सरणी में जोड़ना चाहूंगा, मान कहें 4, जैसा कि निम्नलिखित उदाहरण में है:

val array2 = array + 4     // will not compile

मैं निश्चित रूप से इसका उपयोग कर सकता हूं System.arraycopy()और अपने दम पर कर सकता हूं, लेकिन इसके लिए एक स्काला लाइब्रेरी फ़ंक्शन होना चाहिए, जो मुझे बस नहीं मिला। किसी भी संकेत के लिए धन्यवाद!

टिप्पणियाँ:

  1. मुझे पता है कि मैं निम्नलिखित पंक्ति में जैसे तत्वों के एक और सरणी को जोड़ सकता हूं, लेकिन यह भी गोल-गोल लगता है:

    val array2b = array ++ Array( 4 )     // this works
  2. मुझे सूची बनाम एरे के फायदों और कमियों के बारे में पता है और यहां मैं विभिन्न कारणों से हूं जो विशेष रूप से एक ऐरे को बढ़ाने में रुचि रखते हैं।

संपादित करें 1

:+ऑपरेटर विधि की ओर इशारा करते हुए उत्तर के लिए धन्यवाद । यह वही है जिसे मैं देख रहा था। दुर्भाग्य से, यह एक कस्टम परिशिष्ट () विधि के उपयोग से धीमी है arraycopy- लगभग दो से तीन गुना धीमी। में कार्यान्वयन को देखते हुए SeqLike[], एक बिल्डर बनाया जाता है, फिर उसके साथ सरणी को जोड़ा जाता है, फिर बिल्डर के माध्यम से एपेंड किया जाता है, फिर बिल्डर को प्रदान किया जाता है। सरणियों के लिए एक अच्छा कार्यान्वयन नहीं है। मैंने दो तरीकों की तुलना करते हुए एक त्वरित बेंचमार्क किया, दस चक्रों में से सबसे तेज़ समय को देखते हुए। एकल-आइटम परिशिष्ट के 10 मिलियन पुनरावृत्तियों को किसी वर्ग के 8-तत्व सरणी उदाहरण के लिए Foo3.1 सेकंड के साथ :+और 1.7 सेकंड append()का उपयोग करना आसान विधि के साथ होता हैSystem.arraycopy();लांग के 8-तत्व सरणियों पर 10 मिलियन एकल-आइटम परिशिष्ट पुनरावृत्ति करना 2.1 सेकंड के साथ :+और 0.78 सेकंड सरल append()विधि के साथ लेता है । आश्चर्य है कि अगर यह पुस्तकालय में कस्टम कार्यान्वयन के लिए तय नहीं किया जा सकता है Array?

संपादित करें २

इसके लायक क्या है, मैंने एक टिकट दायर किया: https://issues.scala-lang.org/browse/SI-5017


11
उपयोग ArrayBufferऔर उसकी +=विधि क्यों नहीं ? यह आपको परिशोधित ओ (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
यह किसी भी अन्य स्केला ऑर्डर किए गए संग्रह के लिए समान है , यह उदाहरण के लिए सेट के साथ काम नहीं करता है (जैसा कि प्रीपेन्ड और एपेंड एक सेट के लिए कुछ भी मतलब नहीं है)।
निकोलस

@ नोइकोल्स कोई भी सीक्वेंस। आदेश दिया मतलब अनुसार क्रमबद्ध
डैनियल सी। सोबरल सेप

@ डैनियल हां, मेरे पास एक छोटा सा मेमोरी होल है, जब मैंने टिप्पणी लिखी थी और मुझे स्पष्ट शब्द "अनुक्रम" नहीं मिला था
निकोलस

@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 संग्रह ऐपेंड () पद्धति का उपयोग नहीं करता है, ठीक ArrayBuffer की तरह। मेरी राय में, यह एक नए ऑपरेटर के उपयोग की तुलना में अधिक समन्वय और एकीकरण है: + / +:
Djvu

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.