📜 ⬆️ ⬇️

Let's beat Ruby together! Drop five

We continue ( 1 , 2 , 3 , 4 ) to study Ruby. This time it will touch the arrays. But let's start with the ranges.

Ranges of values


Sometimes it is useful to be able to keep the “concept” of a simple list, and we want to declare it as simple as possible, for example: a list of letters from A to Z, or numbers from 1 to 25. With the help of ranges , they are possible in Ruby as much as possible intuitive. Here are simple numeric ranges:

digits = 0..9
scale1 = 0..10
scale2 = 0...10 #digits = scale2


The operator .. includes the final value, and ... - no (stupid - it seemed that it should be the other way around). However, the ranges themselves are little used.
')

Arrays


Simple variables are sometimes not suitable for real programming. Every modern PL, incl. and Ruby, supports more complex forms of structured data. In Ruby, you can represent ordered sets of objects using arrays .

Ruby arrays are dynamic : you can (but not necessarily) specify the size of the array when you create it. After that, it can grow without the participation of the programmer, so in practice it is rarely even necessary to find out its size. Ruby arrays are heterogeneous : they can store data of a wide variety of data types (to be exact, the array stores only references to objects). Three identical arrays:

a = Array.[](1,2,3,4)
b = Array[1,2,3,4]
c = [1,2,3,4]


To create arrays, a special class method [] . There is also a new method that takes 0, 1 or two parameters: the first is the number of elements, the second is their value. See an example:

d = Array.new #
e = Array.new(3) # [nil, nil, nil]
f = Array.new(3, "ruby") # ["ruby", "ruby", "ruby"]


A frequent mistake of beginners - we believe that the elements are independent of each other. However, as mentioned earlier, the array contains only references to a single object. To avoid this behavior, we use a block (we already met it in the second drop - this is the code between {} ):

f[0].capitalize! # f : ["Ruby", "Ruby", "Ruby"]
g = Array.new(3) { "ruby" } # ["ruby", "ruby", "ruby"]
g[0].capitalize! # g : ["Ruby", "ruby", "ruby"]


Appeal to the elements and the establishment of their values ​​are performed using the methods [] and []= respectively. Each can accept one or two (beginning and length) parameters or a range. The countdown from the end of the array starts at -1 . Values ​​can also be delete_at special simple at method - it takes only one parameter and therefore works a little faster, delete_at will delete the element. We look:

a = [1, 2, 3, 4, 5, 6]
b = a[0] # 1
c = a.at(0) # 1
d = a[-2] # 5
e = a.at(-2) # 5
f = a[9] # nil
g = a.at(9) # nil
h = a[3,3] # [4, 5, 6]
i = a[2..4] # [3, 4, 5]
j = a[2...4] # [3, 4]

a[1] = 8 # [1, 8, 3, 4, 5, 6]
a[1,3] = [10, 20, 30] # [1, 10, 20, 30, 5, 6]
a[0..3] = [2, 4, 6, 8] # [2, 4, 6, 8, 5, 6]
a[-1] = 12 # [2, 4, 6, 8, 5, 12]

a.delete_at(3) # [1, 2, 4, 5, 6]
a.delete_at(9) # nil


Another way is pushing data. The join method “merges” the elements of an array into one variable; we specify the separator as a parameter:

x = []
x << "Word"
x << "Play" << "Fun"
puts x.join(', ') # Word, Play, Fun


The first and last methods return the first and last elements of the array, respectively, and values_at - an array containing only the selected elements:

x = ["alpha", "beta", "gamma", "delta", "epsilon"]
a = x.first # alpha
b = x.values_at(0..2,4) # [alpha, beta, gamma, epsilon]


The length method and its size alias return the number of elements in the array, and nitems will not count empty elements ( nil ), compact will remove nil from the array altogether:

y = [1, 2, nil, nil, 3, 4]
c = y.size # 6
e = y.nitems # 4
d = y.compact # [1, 2, 3, 4]


The easiest method to sort an array is sort (try it yourself). Sorting works only in arrays containing elements that can be compared - with arrays with mixed data types, the method will return an error. Sort the mixed array, converting its elements into strings on the fly (transform to to_s method):

a = [1, 2, "three", "four", 5, 6]
b = a.sort {|x,y| x.to_s <=> y.to_s}
# b [1, 2, 5, 6, "four", "three"]


How it works? <=> is one of the comparison methods (see the third drop). The block returns -1 if the first element of the pair being compared is smaller (then the method swaps the elements), 0 if the elements are equal, 1 if more (in the last two cases, we leave the elements in place). Therefore, for a decreasing order, you simply swap the compared elements ( {|x,y| y.to_s <=> x.to_s} ). I think we understood everything.

To select elements from an array by the criteria, use detect ( find - its synonym) and find_all ( select - the same); we find_all expression into the block:

x = [5, 8, 12, 9, 4, 30]
# find ,
x.find {|e| e % 6 == 0 } # 12
# select
x.select {|e| e % 6 == 0} # [12, 30]


The reject method is the reverse of select — it will remove every element that satisfies the block:

x = [5, 8, 12, 9, 4, 30]
d = c.reject {|e| e % 2 == 0} # [5, 9]


delete deletes all elements containing specific data:

c = ["alpha", "beta", "gamma", "delta"]
c.delete("delta")
# = ["alpha", "beta", "gamma"]


In the class of arrays, the each iterator is defined - it works simply, guess what this code does:

[1, "test", 2, 3, 4].each { |element| puts element.to_s + "X" }

You can create a copy of the array and change it on the fly with the collect iterator:

[1, 2, 3, 4].collect { |element| element * 2 } #[2, 4, 6, 8]

We combine arrays:

x = [1, 2, 3]
y = ["a", "b", "c"]
z = x + y #[1, 2, 3, "a", "b", "c"]


a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
a — b # [1, 2] —
a & b # [3, 4] —
a | b # [1, 2, 3, 4, 5, 6] —
a*2 # [1, 2, 3, 4, 1, 2, 3, 4] -


Epilogue


The drop turned out to be relatively “tough” - yes, all this needs to be known: (Let's get used to it;) If something is not clear, then you will be cherished in a comment - it will help. We are also waiting for feedback and comments!

Further we will return to data types, we will go deep into work with strings and numbers. This time, thanks for the examples sent to Hal Fulton.

Source: https://habr.com/ru/post/48859/


All Articles