> For the complete documentation index, see [llms.txt](https://evgenii-afanasev.gitbook.io/ruby-course/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://evgenii-afanasev.gitbook.io/ruby-course/2_basics/7_arrays.md).

# Массивы

Мы изучили базовые типы данных такие как Boolean, String, Integer и изучили последовательность Range. Давайте поговорим про базовую структуру данных - массив.

Массив (Array) - множество значений объединенных в одной структуре данных. По сути это структура, которая содержит в себе **упорядоченное множество** элементов. Это может быть массив строк, или массив чисел, а может включать и то и то. Хорошей практикой является хранить в массиве элементы одного и того же типа данных, так как часто приходится обрабатывать этот массив, а если в нем содержатся и строки и числа, то поведение программы поменяется. Пожалуй проще всего представлять массив на большую коробку, в которой есть набор маленьких коробок, внутри которых содержится значение

```ruby
# способ создания массива
 # как можно увидеть, при создании мы перендаем сразу несколько значений
arr = Array.new(1, 2, 3, 4)

# Ранее мы работали с циклом на примере Range
# Но массив как и Range это лишь один из варианта реализации множества
for x in arr
  # В данном случае мы сначала распечатаем 1, потом 2, потом 3, потом 4
  puts x
end

# А этог упрощенный способ создания массивов
arr_simplify = [5, 6, 7, 8]

for x in arr_simplify
  # В данном случае мы сначала распечатаем 5, потом 6, потом 7, потом 8
  puts x
end
```

Мы также можем получать полезную информацию о массиве, например его длину. **Важно** длина массива соответсвует реальному размеру, а не индексу. Важно всегда про это помнить, чтобы не допускать ошибки

```ruby
int_arr = [1, 2, 3, 4]

arr_length = int_arr.length # = 4, хотя индекс последнего элемента равен 3
```

Кроме того мы можем получать точечный доступ к нашим элементам по его *индексу*. Индекс - местоположение элемента по счету. Так как массив это упорядоченная структура данных, то элементы расположены строго в том порядке, в каком они были добавлены. **Важно** индекс массива начнается с 0, а не с 1 как это можно подумать.

```ruby
arr_for_getting_by_index = [84312, 2354, 66, 12, 9]

first_element = arr_for_getting_by_index[0] # = 84312, так как это первый элемент, а значит индекс 0
second_element = arr_for_getting_by_index[1] # = 2354, так как это второй элемент, а значит индекс 1

# В данном случае мы создали цикл не для значений массива, а для его индексов, учитывая, что длина массива всегда на +1 больше индексма последнего элемента
for index in (0..arr_for_getting_by_index.length - 1)
    puts "element of array by index = #{index} is #{arr_for_getting_by_index[index]}"
end
```

Можно подумать, что примеров использования у массива не так много, но давайте посмотрим на пример конструкции (метода) `.split` у `String`:

```ruby
    # наша исходная фраза
    welcome = 'You are welcome'
    # .split(delimeter) - консрукция (метод) разбиения строки на массив слов по определенному правилу переданному в его аргументы
    # В данном примере мы в качестве аргумента передаем строку состоящую из 1 пробела. 
    # В метод также можно передавать регулярное выражение, но эту тему мы изучим в дальнейших уроках
    words = welcome.split(' ') # = ['You', 'are', 'welcome']
```

Даже если пойти немного глубже, то можно выяснить, что сама по себе строка это всего лишь массив симолов и работать мы можем с ней точно также как и с массивом

```ruby
    characters = 'Example'
    puts characters[0] # = E
    
    # с помощью цикла мы обходим каждую букву слова на каждый цикл
    for char in characters
        puts char # сначала будет буква E, потом x, потом a и тд.
    end
```

Также массив это изменяемая структура. Мы можем добавлять новые элементы, изменять значения, удалять элементы.

```ruby
# заранее созданный массив с 3 элементами
source_arr = [1, 2, 3]
# пустой массив
target_arr = []

# циклом обходим все индексы массива
for index in (0..source_arr.length)
    # .push(element) позволяет нам добавить в массив новые элементы
    # в данном случае мы добавляем поочередно значения из source_arr по индексу
    target_arr.push(source_arr[index])
    # .delete(index) позволяет удалять наши элементы по его индексу
    source_arr.delete(index)
end

puts "source array: #{source_arr}" # = []. как можем увидеть, наш изначальный массив стал пустым
puts "target array: #{target_arr}" # = [1, 2, 3]. а наш пустой массив содержит в таком же порядке элементы из исходного массива

# вспоминаем совет про маленькие коробки внутри большой коробки
# В данном случае мы кладем в малеьнкую коробку по индексу новое значение, затирая старое
target[0] = 9 

puts "target array: #{target_arr}" # =  [9, 2, 3]

# а теперь попробуем изменить индекс, которого не существует в массиве
target[10] = 87


```

А что будем если изменить индекс, которого не существует ?

```ruby
arr = [0, 9, 8]

# p позволяет нам иследовать полностью внутренность массива, а не просто красиво его распечатать в консоли
# подробнее про этот метод говорилось в доп. материале 1_prepare/4_first_program
p target_arr # = [0, 9, 8]
puts target_arr.length # = 3
arr[10] = 87

# может показаться, что добавился просто элемент, но нет
puts target_arr.inspect # =  [0, 9, 8, nil, nil, ... , 87]
# На самом деле наш массив увеличил размер до своего последнего индекса, а все достающие элементы заполнил nil
puts target_arr.length # = 11
```

Старайтесь аккуратнее работать с массивом на уровне индексов, так как в последующем при обработке массива придется лишний раз проверять является ли элемент `nil` или нет, что заметно усложнит структуру кода.

Как мы помним массив может содержать любые значения в себе, в том числе и сам массив или любую другую структуру данных, как и любая другая структура данных может хранить в себе массив. Массив, который содержит себе вложенный массив называется двумерным, массив, который состоит из массивов, которые состоят из массивов называется трехмерный и тд.

```ruby
    # Двумерный массив
    arr_in_arr = [[0, 1], [16, 4], [98, 12]]
```

## Задание reverse

* Получите из консоли введенную пользователем строку и разбейте ее на массив слов
* разверните массив в обратную сторону
* \*Реализуйте 2 пункт с помощью инструментов из урока не прибегая к использованию новых

Пример:

`Hello world` -> `[Hello, world]` -> `[world, Hello]`

## Задание med\_clinic

* Создайте массив типа `Float` с температурами 30 пациентов (от 32 до 40 градусов).
* Напишите код, который выводит среднюю температуру по больнице и количество здоровых пациентов (с температурой от 36,2 до 36,9), а также температуры всех пациентов.

Рекомендации:

* Помним про [rand(...)](https://blog.appsignal.com/2018/07/31/generating-random-numbers-in-ruby.html)
* При написании программы выносите 'магические числа' в отдельные переменные

```ruby
# Вообще не понятно что это за массив, что в нем находится
for x in [23, 30, 15, 90, 11]
  # непонятно что это ха число 21, для чего мы это делаем
  if x > 21
    puts x
  end
end 

# теперь у нас есть представление что это за цифры хотя бы
user_ages = [23, 30, 15, 90, 11]
# и что это за число
limit_age = 21

# не зная точно какое задание выполнялось мы уже можем понять, что мы обходим возраст пользователей
for age in user_ages
  # и если возраст больше лимита
  if age > limit_age
    # то мы его пропускаем и печатаем
    puts age
  end
end 
```

## Задание cross

Создайте с помощью циклов двумерный массив строк. При его распечатке в консоли должен выводиться крестик из X:

```
    x     x
     x   x
      x x
       x
      x x
     x   x
    x     x
```

## Задание todo\_list

Разработайте список дел, который управляется командами в консоли. Команды: LIST, ADD, EDIT, DELETE.&#x20;

Принцип работы команд:

* LIST — выводит дела с их порядковыми номерами;
* ADD — добавляет дело в конец списка или дело на определённое место, сдвигая остальные дела вперёд, если указать номер;&#x20;
* EDIT — заменяет дело с указанным номером;
* DELETE — удаляет.

Примеры команд

* LIST
* ADD Какое-то дело
* ADD 4 Какое-то дело на четвёртом месте
* EDIT 3 Новое название дела
* DELETE 7  Команды вводятся одной строкой пользователем в консоль.

## Дополнительный материал

* [Еще немного о массивах](https://www.rubyguides.com/2015/05/ruby-arrays/)
* [проверка на пустоту](https://www.bootrails.com/blog/ruby-nil-vs-blank-vs-empty-vs-presence/)
* [магическое число](https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%BE_\(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\))
