Я предполагаю, что цель состоит в том, чтобы найти индекс первого элемента самой длинной последовательности равных элементов в данном массиве.
my_array = [100, 101, 100, 102, 100, 100, 101, 100, 250, 251, 253, 260, 250, 200,
100, 100, 100, 100, 100, 100, 100, 100, 100,
120]
Здесь это будет 14
, индекс 100
, за которым следуют еще 8 100
.
Мы можем сделать это следующим образом.
my_array.each_index.chunk { |i| my_array[i] }.
max_by { |_,a| a.size }.
last.
first
#=> 14
Шаги следующие.
enum0 = my_array.each_index
#=> #<Enumerator: [100, 101, 100,..., 100, 120]:each_index>
Мы можем увидеть элементы, которые будут сгенерированы этим перечислителем, преобразовав его в массив.
enum0.to_a
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
# 17, 18, 19, 20, 21, 22, 23]
Постоянно
enum1 = enum0.chunk { |i| my_array[i] }
#=> #<Enumerator: #<Enumerator::Generator:0x000058d8d09ec8a0>:each>
Ввиду возвращаемого значения вышеприведенного выражения, enum1
можно рассматривать как составной перечислитель , хотя Ruby не имеет такой концепции. Посмотрим, сгенерируют значения enum1
.
enum1.to_a
#=> [[100, [0]], [101, [1]], [100, [2]], [102, [3]], [100, [4, 5]],
# [101, [6]], [100, [7]], [250, [8]], [251, [9]], [253, [10]],
# [260, [11]], [250, [12]], [200, [13]],
# [100, [14, 15, 16, 17, 18, 19, 20, 21, 22]],
# [120, [23]]]
Постоянно
a = enum1.max_by { |v,a| a.size }
#=> [100, [14, 15, 16, 17, 18, 19, 20, 21, 22]]
Поскольку v
не используется в блоке, это выражение обычно пишется:
a = enum1.max_by { |_,a| a.size }
Наличие подчеркивания (допустимой локальной переменной) сигнализирует читателю, что эта переменная блока не используется в расчете блока. Последние два шага следующие.
b = a.last
#=> [14, 15, 16, 17, 18, 19, 20, 21, 22]
b.first
#=> 14
См. Enumerable # chunk и Enumerable # max_by .