Scala Language
संग्रह
खोज…
एक सूची को क्रमबद्ध करें
निम्नलिखित सूची के अनुसार हम विभिन्न प्रकारों को क्रमबद्ध कर सकते हैं।
val names = List("Kathryn", "Allie", "Beth", "Serin", "Alana")
sorted()
का डिफ़ॉल्ट व्यवहार math.Ordering
का उपयोग math.Ordering
, जिसके परिणामस्वरूप तार एक लेक्सोग्राफ़िक सॉर्ट में परिणाम होते हैं:
names.sorted
// results in: List(Alana, Allie, Beth, Kathryn, Serin)
sortWith
आप एक तुलना समारोह का उपयोग कर अपने खुद के आदेश प्रदान करने की अनुमति देता है:
names.sortWith(_.length < _.length)
// results in: List(Beth, Allie, Serin, Alana, Kathryn)
sortBy
आपको एक परिवर्तन फ़ंक्शन प्रदान करने की अनुमति देता है:
//A set of vowels to use
val vowels = Set('a', 'e', 'i', 'o', 'u')
//A function that counts the vowels in a name
def countVowels(name: String) = name.count(l => vowels.contains(l.toLower))
//Sorts by the number of vowels
names.sortBy(countVowels)
//result is: List(Kathryn, Beth, Serin, Allie, Alana)
आप `रिवर्स का उपयोग करके हमेशा सूची या क्रमबद्ध सूची को उल्टा कर सकते हैं:
names.sorted.reverse
//results in: List(Serin, Kathryn, Beth, Allie, Alana)
जावा विधि java.util.Arrays.sort
और इसके स्काला रैपर scala.util.Sorting.quickSort
का उपयोग करके सूची को भी सॉर्ट किया जा सकता है।
java.util.Arrays.sort(data)
scala.util.Sorting.quickSort(data)
अगर संग्रह रूपांतरण और अनबॉक्सिंग / बॉक्सिंग से बचा जा सकता है तो बड़े संग्रह को छांटते समय ये विधियां प्रदर्शन को बेहतर बना सकती हैं। प्रदर्शन के अंतर के बारे में अधिक विस्तृत चर्चा के लिए, स्काला कलेक्शन, सॉर्टविथ और सॉर्टबाय प्रदर्शन के बारे में पढ़ें।
X की n प्रतियों वाली एक सूची बनाएँ
कुछ ऑब्जेक्ट x
की n
प्रतियों का संग्रह बनाने के लिए, भरण विधि का उपयोग करें। यह उदाहरण एक List
बनाता है, लेकिन यह अन्य संग्रह के साथ काम कर सकता है जिसके fill
अर्थ है:
// List.fill(n)(x)
scala > List.fill(3)("Hello World")
res0: List[String] = List(Hello World, Hello World, Hello World)
सूची और वेक्टर धोखा दे
अब
List
बजायVector
का उपयोग करना सबसे अच्छा अभ्यास है क्योंकि कार्यान्वयन में बेहतर प्रदर्शन है प्रदर्शन विशेषताओं को यहां पाया जा सकता है । जहाँ भीList
का उपयोग किया जाता है, वहांVector
का उपयोग किया जा सकता है।
सूची निर्माण
List[Int]() // Declares an empty list of type Int
List.empty[Int] // Uses `empty` method to declare empty list of type Int
Nil // A list of type Nothing that explicitly has nothing in it
List(1, 2, 3) // Declare a list with some elements
1 :: 2 :: 3 :: Nil // Chaining element prepending to an empty list, in a LISP-style
तत्व को लें
List(1, 2, 3).headOption // Some(1)
List(1, 2, 3).head // 1
List(1, 2, 3).lastOption // Some(3)
List(1, 2, 3).last // 3, complexity is O(n)
List(1, 2, 3)(1) // 2, complexity is O(n)
List(1, 2, 3)(3) // java.lang.IndexOutOfBoundsException: 4
Prepend Elements
0 :: List(1, 2, 3) // List(0, 1, 2, 3)
तत्व जोड़ें
List(1, 2, 3) :+ 4 // List(1, 2, 3, 4), complexity is O(n)
सम्मिलित हों (कॉनकैटनेट) सूची
List(1, 2) ::: List(3, 4) // List(1, 2, 3, 4)
List.concat(List(1,2), List(3, 4)) // List(1, 2, 3, 4)
List(1, 2) ++ List(3, 4) // List(1, 2, 3, 4)
आम संचालन
List(1, 2, 3).find(_ == 3) // Some(3)
List(1, 2, 3).map(_ * 2) // List(2, 4, 6)
List(1, 2, 3).filter(_ % 2 == 1) // List(1, 3)
List(1, 2, 3).fold(0)((acc, i) => acc + i * i) // 1 * 1 + 2 * 2 + 3 * 3 = 14
List(1, 2, 3).foldLeft("Foo")(_ + _.toString) // "Foo123"
List(1, 2, 3).foldRight("Foo")(_ + _.toString) // "123Foo"
मानचित्र संग्रह धोखा देती है
ध्यान दें कि यह प्रकार के
Map
संग्रह के निर्माण से संबंधित है, जोmap
विधि से अलग है।
मानचित्र निर्माण
Map[String, Int]()
val m1: Map[String, Int] = Map()
val m2: String Map Int = Map()
एक मानचित्र को अधिकांश कार्यों के लिए tuples
संग्रह माना जा सकता है, जहां पहला तत्व कुंजी है और दूसरा मूल्य है।
val l = List(("a", 1), ("b", 2), ("c", 3))
val m = l.toMap // Map(a -> 1, b -> 2, c -> 3)
तत्व प्राप्त करें
val m = Map("a" -> 1, "b" -> 2, "c" -> 3)
m.get("a") // Some(1)
m.get("d") // None
m("a") // 1
m("d") // java.util.NoSuchElementException: key not found: d
m.keys // Set(a, b, c)
m.values // MapLike(1, 2, 3)
तत्व जोड़ें
Map("a" -> 1, "b" -> 2) + ("c" -> 3) // Map(a -> 1, b -> 2, c -> 3)
Map("a" -> 1, "b" -> 2) + ("a" -> 3) // Map(a -> 3, b -> 2)
Map("a" -> 1, "b" -> 2) ++ Map("b" -> 3, "c" -> 4) // Map(a -> 1, b -> 3, c -> 4)
आम संचालन
संचालन में जहां एक मानचित्र पर एक पुनरावृत्ति होती है ( map
, find
, forEach
, आदि), संग्रह के तत्व tuples
। फ़ंक्शन पैरामीटर या तो ट्यूपल _1
( _1
, _2
) का उपयोग कर सकता है, या केस ब्लॉक के साथ आंशिक फ़ंक्शन:
m.find(_._1 == "a") // Some((a,1))
m.map {
case (key, value) => (value, key)
} // Map(1 -> a, 2 -> b, 3 -> c)
m.filter(_._2 == 2) // Map(b -> 2)
m.foldLeft(0){
case (acc, (key, value: Int)) => acc + value
} // 6
मानचित्र और फ़िल्टर एक संग्रह पर
नक्शा
एक संग्रह भर में 'मैपिंग' का उपयोग करता map
एक समान तरीके से कि संग्रह के प्रत्येक तत्व को बदलने के लिए कार्य करते हैं। सामान्य वाक्यविन्यास है:
val someFunction: (A) => (B) = ???
collection.map(someFunction)
आप एक अनाम फ़ंक्शन प्रदान कर सकते हैं:
collection.map((x: T) => /*Do something with x*/)
पूर्णांक संख्याओं को दो से गुणा करना
// Initialize
val list = List(1,2,3)
// list: List[Int] = List(1, 2, 3)
// Apply map
list.map((item: Int) => item*2)
// res0: List[Int] = List(2, 4, 6)
// Or in a more concise way
list.map(_*2)
// res1: List[Int] = List(2, 4, 6)
फ़िल्टर
जब आप किसी संग्रह के कुछ तत्वों को बाहर करना या 'फ़िल्टर करना' करना चाहते हैं तो filter
का उपयोग किया जाता है। map
साथ, सामान्य वाक्यविन्यास एक फ़ंक्शन लेता है, लेकिन उस फ़ंक्शन को एक Boolean
वापस करना होगा:
val someFunction: (a) => Boolean = ???
collection.filter(someFunction)
आप सीधे एक अनाम फ़ंक्शन प्रदान कर सकते हैं:
collection.filter((x: T) => /*Do something that returns a Boolean*/)
जोड़ी संख्याओं की जाँच करना
val list = 1 to 10 toList
// list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// Filter out all elements that aren't evenly divisible by 2
list.filter((item: Int) => item % 2==0)
// res0: List[Int] = List(2, 4, 6, 8, 10)
अधिक मानचित्र और फ़िल्टर उदाहरण
case class Person(firstName: String,
lastName: String,
title: String)
// Make a sequence of people
val people = Seq(
Person("Millie", "Fletcher", "Mrs"),
Person("Jim", "White", "Mr"),
Person("Jenny", "Ball", "Miss") )
// Make labels using map
val labels = people.map( person =>
s"${person.title}. ${person.lastName}"
)
// Filter the elements beginning with J
val beginningWithJ = people.filter(_.firstName.startsWith("J"))
// Extract first names and concatenate to a string
val firstNames = people.map(_.firstName).reduce( (a, b) => a + "," + b )
स्काला कलेक्शंस का परिचय
स्काला कलेक्शंस की रूपरेखा, इसके लेखकों के अनुसार , इसका उपयोग, संक्षिप्त, सुरक्षित, तेज और सार्वभौमिक बनाने में आसान है।
फ्रेमवर्क स्कैला लक्षणों से बना है, जो संग्रह बनाने के लिए ब्लॉक बनाने के लिए डिज़ाइन किए गए हैं। इन इमारत ब्लॉकों के बारे में अधिक जानकारी के लिए, आधिकारिक स्काला संग्रह अवलोकन पढ़ें ।
ये बिल्ट-इन संग्रह अपरिवर्तनीय और परिवर्तनशील पैकेजों में अलग किए गए हैं। डिफ़ॉल्ट रूप से, अपरिवर्तनीय संस्करणों का उपयोग किया जाता है। एक List()
(कुछ भी आयात किए बिना) का निर्माण एक अपरिवर्तनीय सूची का निर्माण करेगा।
फ्रेमवर्क की सबसे शक्तिशाली विशेषताओं में से एक समान दिमाग वाले संग्रह में लगातार और आसानी से उपयोग होने वाला इंटरफ़ेस है। उदाहरण के लिए, एक संग्रह में सभी तत्वों को सूचीबद्ध करें सूची, सेट, क्षेत्र, Seq और Arrays के लिए समान है:
val numList = List[Int](1, 2, 3, 4, 5)
numList.reduce((n1, n2) => n1 + n2) // 15
val numSet = Set[Int](1, 2, 3, 4, 5)
numSet.reduce((n1, n2) => n1 + n2) // 15
val numArray = Array[Int](1, 2, 3, 4, 5)
numArray.reduce((n1, n2) => n1 + n2) // 15
ये तरह-तरह के विचार Traversable
विशेषता से विरासत में Traversable
।
अब
List
बजायVector
का उपयोग करना सबसे अच्छा अभ्यास है क्योंकि कार्यान्वयन में बेहतर प्रदर्शन है प्रदर्शन विशेषताओं को यहां पाया जा सकता है । जहाँ भीList
का उपयोग किया जाता है, वहांVector
का उपयोग किया जा सकता है।
ट्रैवर्सेबल प्रकार
संग्रह वर्गों है कि Traversable
विशेषता लागू foreach
और संग्रह करने के लिए आम ऑपरेशनों को करने के इनहेरिट कई तरीके है, जो सभी समारोह हूबहू। सबसे आम संचालन यहां सूचीबद्ध हैं:
- मानचित्र -
map
,flatMap
, और मूल संग्रह में प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करके नए संग्रह का उत्पादनcollect
हैं।
List(1, 2, 3).map(num => num * 2) // double every number = List(2, 4, 6)
// split list of letters into individual strings and put them into the same list
List("a b c", "d e").flatMap(letters => letters.split(" ")) // = List("a", "b", "c", "d", "e")
- रूपांतरण -
toList
,toArray
, और कई अन्य रूपांतरण ऑपरेशन वर्तमान संग्रह को अधिक विशिष्ट प्रकार के संग्रह में बदलते हैं। ये आमतौर पर 'से' के लिए प्रचलित तरीके होते हैं और अधिक विशिष्ट प्रकार (यानी 'लिस्ट' एकList
परिवर्तित होते हैं)।
val array: Array[Int] = List[Int](1, 2, 3).toArray // convert list of ints to array of ints
- आकार की जानकारी -
isEmpty
,nonEmpty
,size
, औरhasDefiniteSize
सेट के बारे में सभी मेटाडाटा कर रहे हैं। यह संग्रह पर सशर्त संचालन की अनुमति देता है, या कोड के संग्रह के आकार को निर्धारित करने के लिए, जिसमें यह अनंत या असतत है।
List().isEmpty // true
List(1).nonEmpty // true
- तत्व पुनर्प्राप्ति -
head
,last
,find
, और उनकेOption
वेरिएंट का उपयोग पहले या अंतिम तत्व को पुनः प्राप्त करने के लिए किया जाता है, या संग्रह में एक विशिष्ट तत्व ढूंढता है।
val list = List(1, 2, 3)
list.head // = 1
list.last // = 3
- उप-संग्रह पुनर्प्राप्ति संचालन -
filter
,tail
,slice
,drop
, और अन्य संचालन आगे के संचालन के लिए संग्रह के कुछ हिस्सों को चुनने की अनुमति देते हैं।
List(-2, -1, 0, 1, 2).filter(num => num > 0) // = List(1, 2)
- उपखंड संचालन -
partition
,splitAt
,span
औरgroupBy
वर्तमान संग्रह को विभिन्न भागों में विभाजित करते हैं।
// split numbers into < 0 and >= 0
List(-2, -1, 0, 1, 2).partition(num => num < 0) // = (List(-2, -1), List(0, 1, 2))
- तत्व परीक्षण -
exists
,forall
, औरcount
इस संग्रह की जांच करने के लिए उपयोग किए जाने वाले संचालन हैं यह देखने के लिए कि क्या यह एक विधेय को संतुष्ट करता है।
List(1, 2, 3, 4).forall(num => num > 0) // = true, all numbers are positive
List(-3, -2, -1, 1).forall(num => num < 0) // = false, not all numbers are negative
- सिलवटों -
foldLeft
(/:
),foldRight
(:\
),reduceLeft
, औरreduceRight
संग्रह में लगातार तत्वों के लिए द्विआधारी कार्यों लागू किया जाता है। गुना उदाहरणों के लिए यहां जाएं और उदाहरणों को कम करने के लिए यहां जाएं ।
तह
fold
विधि एक संग्रह पर पुनरावृत्ति करती है, एक प्रारंभिक संचायक मान का उपयोग करते हुए और एक फ़ंक्शन को लागू करने के लिए जो संचयकर्ता को सफलतापूर्वक अपडेट करने के लिए प्रत्येक तत्व का उपयोग करता है:
val nums = List(1,2,3,4,5)
var initialValue:Int = 0;
var sum = nums.fold(initialValue){
(accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 15 because 0+1+2+3+4+5 = 15
उपरोक्त उदाहरण में, एक अनाम फ़ंक्शन को fold()
में आपूर्ति की गई थी। आप एक नामित फ़ंक्शन का भी उपयोग कर सकते हैं जो दो तर्क लेता है। मेरे इस संबंध में, उपरोक्त उदाहरण को इस प्रकार फिर से लिखा जा सकता है:
def sum(x: Int, y: Int) = x+ y
val nums = List(1, 2, 3, 4, 5)
var initialValue: Int = 0
val sum = nums.fold(initialValue)(sum)
println(sum) // prints 15 because 0 + 1 + 2 + 3 + 4 + 5 = 15
प्रारंभिक मूल्य बदलने से परिणाम प्रभावित होगा:
initialValue = 2;
sum = nums.fold(initialValue){
(accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 17 because 2+1+2+3+4+5 = 17
fold
विधि के दो संस्करण हैं- foldLeft
और foldRight
।
foldLeft()
उस क्रम में बाएं से दाएं (संग्रह के पहले तत्व से अंतिम तक foldLeft()
से foldLeft()
। foldRight()
दाएं से बाएं (अंतिम तत्व से पहले तत्व) तक पुनरावृत्त होती है। fold()
से बाईं ओर दाईं ओर fold()
जैसे foldLeft()
। वास्तव में, fold()
वास्तव में foldLeft()
आंतरिक रूप से कहते हैं।
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)
fold()
, foldLeft()
और foldRight()
एक मान लौटाएंगे जिसमें प्रारंभिक मान के साथ एक ही प्रकार है। हालाँकि, foldLeft()
और foldRight()
विपरीत, fold()
को दिया गया प्रारंभिक मान केवल एक ही प्रकार का या संग्रह के प्रकार का एक foldRight()
हो सकता है।
इस उदाहरण में ऑर्डर प्रासंगिक नहीं है, इसलिए आप fold()
को foldLeft()
या foldRight()
बदल सकते हैं और परिणाम वही रहेगा। एक फ़ंक्शन का उपयोग करना जो ऑर्डर करने के लिए संवेदनशील है, परिणामों को बदल देगा।
यदि संदेह है, तो foldLeft()
पर foldRight()
प्राथमिकता foldLeft()
। foldRight()
कम foldRight()
है।
प्रत्येक के लिए
foreach
संग्रह के पुनरावृत्तियों में असामान्य है कि यह एक परिणाम नहीं देता है। इसके बजाय यह प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करता है जिसमें केवल साइड इफेक्ट होते हैं। उदाहरण के लिए:
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)
scala> x.foreach { println }
1
2
3
foreach
की आपूर्ति किए गए फ़ंक्शन में कोई भी वापसी प्रकार हो सकता है , लेकिन परिणाम को छोड़ दिया जाएगा । आमतौर पर foreach
का उपयोग तब किया जाता है जब साइड इफेक्ट्स वांछनीय हों। यदि आप map
, filter
, for comprehension
या किसी अन्य विकल्प का उपयोग करके डेटा को रूपांतरित करना चाहते हैं।
परिणाम छोड़ने का उदाहरण
def myFunc(a: Int) : Int = a * 2
List(1,2,3).foreach(myFunc) // Returns nothing
कम करना
reduce()
, reduce()
reduceLeft()
और reduceRight
विधि तह के समान हैं। कम करने के लिए पारित समारोह दो मान लेता है और एक तिहाई उपज देता है। किसी सूची पर काम करते समय, पहले दो मान सूची में पहले दो मान होते हैं। फ़ंक्शन का परिणाम और सूची में अगले मूल्य को फिर से नए परिणाम देने के लिए, फ़ंक्शन पर फिर से लागू किया जाता है। इस नए परिणाम को सूची के अगले मूल्य और इतने पर लागू किया जाता है जब तक कि अधिक तत्व न हों। अंतिम परिणाम वापस आ गया है।
val nums = List(1,2,3,4,5)
sum = nums.reduce({ (a, b) => a + b })
println(sum) //prints 15
val names = List("John","Koby", "Josh", "Matilda", "Zac", "Mary Poppins")
def findLongest(nameA:String, nameB:String):String = {
if (nameA.length > nameB.length) nameA else nameB
}
def findLastAlphabetically(nameA:String, nameB:String):String = {
if (nameA > nameB) nameA else nameB
}
val longestName:String = names.reduce(findLongest(_,_))
println(longestName) //prints Mary Poppins
//You can also omit the arguments if you want
val lastAlphabetically:String = names.reduce(findLastAlphabetically)
println(lastAlphabetically) //prints Zac
फोल्ड फ़ंक्शंस की तुलना में कम कार्य कैसे काम करते हैं, इसमें कुछ अंतर हैं। वो हैं:
- कम किए गए कार्यों का कोई प्रारंभिक संचायक मूल्य नहीं है।
- खाली सूचियों पर कार्यों को कम नहीं किया जा सकता है।
- फ़ंक्शन कम करें केवल सूची के प्रकार या सुपरस्क्रिप्ट को वापस कर सकते हैं।