Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Ruby.docx
Скачиваний:
18
Добавлен:
06.09.2019
Размер:
1.74 Mб
Скачать

8.2.6. Инвертирование хэша

Инвертирование хэша осуществляется в Ruby тривиально с помощью метода invert:

а = {"fred"=>"555-1122","jane"=>"555-7779"}

b = a.invert

b["555-7779"] # "jane"

Поскольку ключи в хэше уникальны, такая операция может привести к потере данных. Значения-дубликаты будут преобразованы в уникальный ключ, которому соответствует какое-то одно из множества прежних значений. Предсказать, какое именно, невозможно.

8.2.7. Поиск ключей и значений в хэше

Определить, было ли присвоено значение некоторому ключу, позволяет метод has_key? или любой из его синонимов include?, key?, member?:

а = {"а"=>1,"b"=>2}

a.has_key? "с" # false

a.include? "а" # true

a.key? 2       # false

a.member? "b"  # true

Можно также воспользоваться методом empty?, чтобы узнать, остался ли в хэше хотя бы один ключ. А метод length и его синоним size позволяют узнать, сколько ключей имеется в хэше:

a.empty? # false

a.length # 2

Можно проверить также, существует ли указанное значение. Для этого предназначены методы has_value? или value?:

a.has_value? 2 # true

a.value? 99    # false

8.2.8. Копирование хэша в массив

Чтобы преобразовать весь хэш в массив, пользуйтесь методом to_a. В получившемся массиве ключи станут элементами с четными индексами (начиная с 0), а значения — с нечетными:

h = {"а"=>1,"b"=>2}

h.to_a # ["а",1,"b",2]

Можно также получить массив, содержащий только ключи или только значения:

h.keys   # ["а","b"]

h.values # [1,2]

Наконец, можно поместить в массив только значения, соответствующие заданному списку ключей. Этот метод работает для хэшей примерно так же, как одноименный метод для массивов. (Кроме того, как и в случае массивов, метод values_at заменяет устаревшие методы indices и indexes.)

h = {1=>"one", 2=>"two", 3=>"three", 4=>"four", "cinco"=>"five"}

h.values_at(3,"cinco",4) # ["three","five","four"]

h.values_at(1,3)         # ["one","three"]

8.2.9. Выборка пар ключ-значение по заданному критерию

К классу Hash подмешан модуль Enumerable, поэтому можно обращаться к методам detect (find), select (find_all), grep, min, max и reject (как и для массивов).

Метод detect (синоним find) находит одну пару ключ-значение. Он принимает блок (которому передается по одной паре за раз) и возвращает первую пару, для которой вычисление блока дает true.

names = {"fred"=>"jones","jane"=>"tucker", "joe"=>"tucker","mary"=>"SMITH"}

# Найти tucker.

names.detect {|k,v| v=="tucker" } # ["joe","tucker"]

# Найти имена, записанные прописными буквами.

names.find {|k,v| v==v.upcase }   # ["mary", "SMITH"]

Разумеется, объекты в хэше могут быть сколь угодно сложными, как и условие, проверяемое в блоке, но сравнение объектов разных типов может оказаться проблематичным.

Метод select (синоним find_all) возвращает все пары, удовлетворяющие условию, а не только первую:

names.select {|k,v| v=="tucker" }

# [["joe", "tucker"], ["jane", "tucker"]]

names.find_all (|k,v| k.count("r")>0}

# [["mary", "SMITH"], ["fred", "jones"]]

8.2.10. Сортировка хэша

Хэши по природе своей не упорядочены ни по ключам, ни по значениям. Чтобы отсортировать хэш, Ruby преобразует его в массив, который затем сортирует. Понятно, что и результатом является массив.

names = {"Jack"=>"Ruby","Monty"=>"Python",

         "Blaise"=>"Pascal", "Minnie"=>"Perl"} list = names.sort

# list равно:

# [["Blaise","Pascal"], ["Jack","Ruby"],

# ["Minnie","Perl"], ["Monty","Python"]]