Summary:
This article mainly learns how to manipulate arrays in Scala. Java and C + + programmers typically use arrays or approximate structures , such as array lists or vectors , to collect a set of elements. In Scala, we have more choices, but now let's assume that we don't care about other choices, but just want to start using arrays right away. The main points of this article include:
1. Use array if the length is fixed, use Arraybuffer if the length may change
2. Do not use new when providing initial values
3. Use () to access the element
4. Use for (Elem<-arr) to traverse the element
5. Use for (Elem<-arr if ...) ... yield ... To transform the original array into a new array
6. Scala arrays and Java arrays can interoperate; with Anaybuffer, use Scalacollection. Conversion functions in the Javaconversions
If you need an array of the same length , you can use the arrays in Scala. For example:
Val nums=New array[INT] (10)//integer array of length 10, all elements initialized to 0
Val a=New array [string] (10)//string array of length 10, all elements initialized to null
Val s= Array ("Hello", "world")///length 2 array[string] Type is inferred, the initial value provided does not require a new
S (0) = "Goodbye"//array ("Goodby", "World"), using () rather than [] to access the element
In the JVM, Scala's array is implemented as a Java array. The array in the example is of type java.lang.string[]in the JVM. An Int, double, or other array corresponding to the base type in Java is an array of primitive types.
For example,Array (2,3,5,7,11) is a int[in the JVM ].
Variable-length arrays: buffering |
End-of-operation Buffer array
For An array of that length that changes as needed,Java has ArrayList, and C + + has vectors. The equivalent data structure in Scala is ArrayBuffer
Import Scala.collection.mutable.ArrayBuffer
Val B=arraybuffer[lnt]//or new ArrayBuffer [int], an empty array buffer, ready to hold integers
B+=1//ArrayBuffer (1), adding elements at the end with + =
b+= (1,2,3,5)//ArrayBuffer (1,1,2,3,5), add multiple elements at the end, wrap them in parentheses
b++= Array (8, 1, 2, 3, 5, 8,13,1)// append any collection with the ++= operator
B.trimend (5)//ArrayBuffer (1, 1, 2), removing the last 5 elements
Adding or removing elements at the end of an array buffer is an efficient operation
Manipulate buffer arrays in any position
You can also insert or remove elements from anywhere, but this is less efficient. All elements that are behind that position must be panned. Examples are as follows:
B. Insert (2,6)//arraybuffer (1, 1, 6, 2), inserting before subscript 2
B.Insert (2,7,8,9)//ArrayBuffer (1, 1,7, 8,9, 6,2), you can insert any number of elements
B.Remove(2)//ArrayBuffer (8,9,6, 2)
B.remove (2,3)//ArrayBuffer(1, 1, 2), the meaning of the 2nd parameter is how many elements to remove
Sometimes you need to build an array, but you don't know how many elements you'll need to load eventually. In this case, first build an array buffer and then call:
B.toarray//Array(1, per)
In turn, call Chaos Tobuffer to convert an array A to an array buffer
Iterating through arrays and array buffers |
Full traversal
In Java and C + +, arrays and array lists / vectors are somewhat different in syntax and Scala is more uniform. Most of the time, you can work with these two data structures in the same code. The following is the syntax for a for loop to iterate through an array or array buffer:
for (i <-0 until a.length)//variable i is evaluated from 0 to a length-1
println (i+ ":" +a (i))
Utii is a method of the Richlnt class that returns all numbers less than, but not including, the upper bound. For example:
0 until//Range (0,1,2,3,4,5,6,7,8, 9)
It is important to note that 0 until 10 is actually a method call:0.until (Ten)
Conditional traversal
The following structure:
for (I <-interval)
Causes the variable i to traverse all values of that interval. For this example, the cyclic variable I takes a value of 0, 1, and so on, until it does not contain a.length. If you want to jump every two elements , you can let I traverse this:
0 until (a.length,2)//range (0,2,4,...)
If you want to start from the end of the array, the traversal is written as:
(0 until A.length). Reverse//range (..., 2,1,0)
If the array subscript is not needed in the loop body, we can also access the array elements directly, like this:
For (Elem <-a)
println (Elem)
This is similar to the "enhanced" for loop in Java, or the "interval-based" for loop in C + +. The variable elem has been set to a (0), then a (1), and so on
Derivation and guard in for
In front, you see how to manipulate arrays like Java or C + +. But in Scala, you can go farther. Starting with an array or array buffer, it is easy to convert it in some way. These conversion actions do not modify the original array , but instead produce a completely new array . Use the for deduction like this:
Val A=array (2, 3, 5, 7, 11)
Val result=for (Elem <-a) yield 2*elem//result is an array (4,6,10, 14, 22)
For (...) The yield loop creates a new collection of the same type as the original collection. If you start with an array, you get another array. If you are starting from an array buffer, then you are in the for (...) Yields after yield are also
is an array buffer
The result contains the value of the expression after yield, which corresponds to one iteration at a time. Typically, when you traverse a collection, you only want to handle those elements that satisfy a particular condition. This requirement can be achieved by guarding :if in for . Here we double the number of even elements and discard the odd elements:
For (Elem <-A If elem%==0) yield 2*elem
Note that the result is a new collection, and the original collection is not affected
An equivalence method
In addition to the above, there is another way
A.filter (_%2==0). Map (2*_)
Even
a.filter {_%2 = = 0} map {2*_}
Some programmers with functional programming experience tend to use filter and map instead of guard and yield, which is just a style that is exactly the same as what the For loop does. You can choose whatever you prefer.
Efficient array manipulation
Consider the following example: Given an array buffer for an integer, we want to remove all negative numbers except for the first negative number. A traditional, sequential solution will place a tag when the first negative number is encountered , and then remove the negative element that continues to appear
var first=true
var n=a.length
var i=0
while (I<n) {
if (A (i) >= 0)
I+=1
else{
if (first) {
First=false
I+=1
} else {
A.remove (i)
N-=1
}
}
}
But the solution is not so good: removing elements from the array buffer is not efficient and copying nonnegative values to the front end is much better.
First, collect the subscript that needs to be retained:
var first= true
Val indexes=for (i <-0 until a.length if first | | A (i) >=0) yield {
if (A (i) <0)
First=false;
I
}
Then move the element to that location and truncate the end:
For (J <-0 until Indexes.length)
A (j) = A (Indexes (j))
A.trimend (A.length-indexes.length)
The key point here is that it's better to get all the subscripts than to deal with them individually
Sum and sort
There is a saying that a large percentage of business operations are simply sums and sorts. Fortunately, Scala has built-in functions to handle these tasks.
Array (1,7,2, 9). sum //19, same for Arraybuffer
To use the sum method , the element type must be a numeric type : Either an integer or a floating-point number or a biglnteger/bigdecimal.
In the same vein, Min and max output the smallest and largest elements in an array or array buffer.
Arrarybuffer ("Mary", "had", "a", "little", "lamb"). Max //"little"
The sorted method sorts the array or array buffers and returns a sorted array or array buffer, and the process does not modify the original version:
Val B=arraybuffer (1,7,2, 9)
Val bsorted=b.sorted (_ < _)//b has not been changed, Bsorted is Arraybuffer (1,2,7,9)
You can also provide a comparison function, but you need to use the Sortwith method:
Val bdescending=b.sorted (_ > _)//ArrayBuffer (9,7,2, 1)
You can sort an array directly, but you cannot sort the array buffers :
Val A=array (1,7,2,9)
Scala.util. Sorting.quicksortia (a)//A is now an array (1,2,7,9)
For the NUM, Max, and Quicksort methods, the element type must support the comparison operation, which includes numbers, strings, and other types with ordered traits.
Display array Contents
Finally, if you want to display the contents of an array or array buffer , you can use the Mkstring method , which allows you to specify the delimiter between the elements. Another overloaded version of the method allows you to specify prefixes and suffixes . For example:
A.mkstring ("and")//"1 and 2 and 7 and 9"
A.mkstring ("<", ",", ">")//"<1,2,7,9>"
Compared with ToString:
a.tostring//"[[Email protected]", which is called Java's meaningless toString method
B.tostring//"ArrayBuffer (l,7,2, 9)", ToString method report type, easy to debug
There are many useful methods for arrays and array buffering, and we can get this information by browsing the Scala documentation. The operation method for the array class is listed under the Arrayops related entry. Technically, arrays are converted to arrayops objects before they are applied on an array.
Because Scala's type system is richer than Java, you may encounter some seemingly strange syntax when browsing Scala's documentation. Fortunately, you don't need to understand all the details of a type system to accomplish a lot of useful
's work. You can make the following table a "decode ring".
and Java , multidimensional arrays are implemented by arrays . For example, adouble's two-dimensional array type is:
Array[array[double]]
To construct such an array, you can use the Ofdim method :
Val Matrix=array.ofdim[double] (3,4)//three rows, four columns to access the elements, use two pairs of parentheses:
Matrix (Row) (column) =42
You can create an irregular array with different lengths for each line :
Val triangle=new Arraylarray [Int] (10)
for (i <-0 until Triangle.length)
Triangle (i) =new array[lnt] (i+1)
Interoperability with Java |
Since the Scala array is implemented in a Java array , you can pass it back and forth between Java and Scala. If you call A Java method that accepts or returns Java.utiI.List, then of course you can use Java's ArrayList in Scala code, but that doesn't make sense. You can completely introduce implicit conversion methods in scala.collection.JavaConversions . This allows you to use Scala buffering in your code, which is automatically packaged as a Java list when calling Java methods.
For example, theJava.lang.ProcessBuilder class has a constructor that takes list<string> as its parameter . Here's how to invoke it in Scala:
Import Scala.collection.JavaConversions. bufferasjavalist
Import scala.collection.mutable. ArrayBuffer
val command = ArrayBuffer("ls", "-al", "/home/cay")
Val pb = new processbuilder(command)//Scala to Java conversion
Scala buffering is packaged as an object for Java classes that implement the Java.util.List interface. Conversely, when the Java method returns Java.util.List, we can make it automatically convert to a buffer:
Import Scala.collection.JavaConversions. Asscalabuffer
Import scala.collection.mutable. Buffer
Val cmd:buffer[string] = Pb.command ()//Java to Scala conversion
It is important to note that objects that cannot be packaged with arraybuffer--can only be guaranteed to be a buffer. If the Java method returns a wrapped Scala buffer , the implicit conversion will unpack the original object . Take this example, cmd = = command. ☆
If you think reading this blog gives you something to gain, you might want to click "recommend" in the lower right corner.
If you want to find my new blog more easily, click on "Follow Me" in the lower left corner.
If you are interested in what my blog is talking about, please keep following my follow-up blog, I am "sunddenly".
This article is copyright to the author and the blog Park, Welcome to reprint, but without the consent of the author must retain this paragraph, and in the article page obvious location to the original link, otherwise reserves the right to pursue legal responsibility.
Scala Learning (iii)----array-related operations