Чтобы удалить из массива повторяющиеся экземпляры, воспользуйтесь методом
uniq
(или его вариантом для модификации на месте
uniq!
):
breakfast = %w[spam spam eggs ham eggs spam]
lunch = breakfast.uniq # ["spam","eggs","ham"]
breakfast.uniq! # Массив breakfast изменился.
8.1.22. Чередование массивов
Предположим,
что есть два массива и надо построить из них третий, который содержит массивы из двух элементов, взятых из соответственных позиций исходных массивов. В последних версиях Ruby модуль
Enumerable
содержит метод
zip
:
a = [1, 2, 3, 4]
b = ["a", "b", "c", "d"]
с = a.zip(b)
# с равно [[1,"а" ] , [2,"b"], [3,"с"], [4,"d"]]
# Чтобы устранить вложенность, воспользуйтесь методом flatten
d = с.flatten
# d равно [1, "а", 2, "b", 3, "с", 4, "d"]
8.1.23. Вычисление частоты различных значений в массиве
Для массивов нет метода
count
, как для строк (чтобы подсчитать число вхождений каждого элемента). Поэтому создадим свой собственный:
Массив нужен для того, чтобы ассоциировать целое число (индекс) с данными. А если нужно инвертировать это отношение, то есть ассоциировать данные с индексом? Иными словами, породить хэш? Это можно сделать так:
class Array
def invert
h={}
self.each_with_index{|x,i| h[x]=i}
h
end
end
a = ["red","yellow","orange"]
h = a.invert # {"orange"=>2, "yellow"=>1, "red"=>0}
8.1.25. Синхронная сортировка нескольких массивов
Предположим, что необходимо
отсортировать массив, которому соответствуют «параллельные» массивы, то есть в соответственных позициях находятся логически связанные данные. Не хотелось бы, чтобы в результате сортировки это соответствие нарушилось.
В представленном ниже решении мы сортируем массив и сохраняем получившийся набор индексов. Затем список индексов (который сам является массивом) можно применить к любому другому массиву, чтобы расставить его элементы в том же порядке.
class Array
def sort_index
d=[]
self.each_with_index{|x, i| d[i]=[x,i]}
if block_given?
d.sort {|x,у| yield x[0],y[0]}.collect{|x| x[1]}
else
d.sort.collect{|x| x[1]}
end
end
def sort_with(ord=[])
return nil if self.length!=ord.length
self.values_at(*ord)
end
end
a = [21, 33, 11, 34, 36, 24, 14]
b = a.sort_index
a2 = a.sort_with(b)
c = a.sort_index {|x,y| x%2 <=> y%2 }
a3 = a.sort_with(c)
p a # [21, 33, 11, 34, 36, 24, 14]
p b # [2,6,0,5,1,3,4]
p a2 # [11, 14, 21, 24, 33, 34, 36]
p c # [6, 5, 4, 3, 2, 1, 0]
p a3 # [14, 24, 36, 34, 11, 33, 21]
8.1.26. Указание значения по умолчанию для новых элементов массива
Когда массив растет и в нем создаются новые элементы, по умолчанию им присваивается значение
nil
:
a = Array.new
a[0]="x"
a[3]="y"
# а равно ["x", nil, nil, "y"]
Но, допустим, нам требуется, чтобы новые элементы получали другое значение. Тогда в качестве конкретного применения общего принципа предлагаем класс
ZArray
, описывающий массив, в котором вновь созданные элементы будут равны 0: