Ruby: работа с массивами

Iteration
each_with_index – из названия понятно, что полезно когда нужен элемент массива и его индекс)
Удаление из массива элементов
.drop(1) – удалить первый элемент (если указать 10 – первые 10 элементов)
a.delete(‘test’) – удалить по значению
arr[0..-3] – удалить последние два элемента
Элемент по ID
В Ruby, как, в принципе, и в PHP,  можно натравить метод какой-то на массив и элемент массива получить в одной строке.
number = array_slice(arr, -1, 1)[0];
Иногда это помогает значительно уменьшить количество строк кода:
date = res.split("<th>Текст<\/th>")[1].split("\n")[3].sub("</td>","").sub(/<(.*)>/,"").strip.split(" ")[0]

Первый, второй, последний, предпоследний элементы

.first(1) # Первый элемент
.first(2).first(1) # Второй элемент
.last(1) # Последний элемент 
.last(2).first(1) # Предпоследний элемент (можно так же запускать на массив из одного элемента)

intersection

Крутая штука intersection – смотрим без итераций есть ли (и если есть, то какие) перекликания в элементах массива.

# простой пример
([2, 6, 13, 99, 27] & [2, 6]).any?

# пример пересечения массива MAC-адресов из таблицы коммутации с массивом заданных MAC
intersect = (marr & macs) 
if !intersect.empty?
 mac = intersect.join(",")
 return [ "success", "#{ip}", "#{p}", "#{mac}" ] if marr.include? "#{mac}"
end

Hash.new(0)

h = Hash.new(0) – позволяет указать дефолтное значение для всех ключей в виде 0. К примеру, это полезно если ключ определяет что-то, а значение инкрементируется – таким образом не нужно определять значение каждого нового ключа. В результатме мы можем сразу использовать конструкцию для подсчета типа:

h = Hash.new(0)
h["admin"] += 1

SELECT/FIND/FIND_ALL

.find и .find_all – методы поиска в массиве не ограничиваются .select, есть так же .find и .find_all.

perl = a.find { |a| a[0] =~ /^Test/ } # выведет первый массив, который соответствует pattern
perl = a.find_all { |a| a[0] =~ /^Test/ } # выведет все массивы, которые соответствуют pattern

.map – позволяет проделать операцию с каждым элементом массива без итерации. Очень удобно.
К примеру одна строка:

 IPAddr.new("#{ip}/#{mask}").to_range.map { |ip_obj| ip_object.to_s }

Замещает 4 строки:

ip_range = []
IPAddr.new("#{ip}/#{mask}").to_range.each do |ip_obj| 
  ip_range.push(ip_obj.to_s)
end

.select – .select позволяет делать условия не только с сравнением string, regexp, но и любые кастомные, получая из array новый array – к примеру без итераций .each можно проверить доступность ip-адресов и сформировать массив из только доступных. В результате как выше с .map:
Одна строка:

ip_range.select { |ip| Net::Ping::Extrenal.new(ip).ping? }

Замещает 7 строк:

active_ip = []
ip_range.each do |ip_addr|
  if Net::Ping::Extrenal.new(ip).ping?
    active_ip.push(ip_addr)
  end
end
active_ip

Leave a Reply