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']]

8.2.11. Объединение двух хэшей

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

dict = {'base'=>'foundation', 'pedestal'=>'base'}

added = {'base'=>'non-acid', 'salt'=>'NaCl'}

new_dict = diet.merge(added)

# {'base' =>'non-acid', 'pedestal' =>'base', 'salt'=>'NaCl'}

У метода merge есть синоним update.

Если задан блок, то он может содержать алгоритм устранения коллизий. В нижеприведенном примере, если два ключа совпадают, в объединенном хэше остается меньшее значение (по алфавиту, по числовому значению или в каком-то ином смысле):

dict = {'base'=>'foundation', 'pedestal'=>'base'}

added = {'base'=>'non-acid', 'salt' =>'NaCl'}

new_dict = diet.merge(added) {|key,old,new| old < new ? old : new }

# {'salt'=>'NaCl', 'pedestal'=>'base', 'base'=>'foundation'}

Таким образом, при использовании блока результат может получиться не такой, как в случае, когда блок не задан. Имеются также методы merge! и update!, которые изменяют вызывающий объект «на месте».

8.2.12. Создание хэша из массива

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

Array =[2,3,4,5,6,7]

hash = Hash[*array]

# hash равно: {2=>3, 4=>5, 6=>7}

8.2.13. Вычисление разности и пересечения хэшей

Ключи хэша можно скопировать в отдельный массив, а к получившимся из разных хэшей массивам применить методы & и - класса Array. Результатом являются пересечение и разность множеств ключей. Соответствующие им значения можно получить с помощью метода each, примененного к хэшу, содержащему все образованные таким способом ключи.

а = {'а'=>1,'b'=>2,'z'=>3}

b = {'x'=>99,'у'=>88,'z'=>77}

intersection = a.keys & b.keys

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату