hash = {
"id" => "sjfdkjfd",
"name" => "Field Name",
"type" => "field",
"options" => ["L", "Q", "Q", "Q", "A", "A", "Q"],
"option_ids" => ["12345", "23456", "34567", "dog", "45678", "56789", "cat"]
}
Я предполагаю, что «повторяющиеся элементы» относятся к смежным равным элементам (2
только в [1,2,2,1]
), в отличие от «дублированных элементов» (как 1
, так и 2
в предыдущем примере).Я действительно показываю, как код будет изменен (фактически упрощен), если будет применена вторая интерпретация.
idx = hash["options"].
each_with_index.
chunk_while { |(a,_),(b,_)| a==b }.
map { |(_,i),*| i }
#=> [0, 1, 4, 6]
hash.merge(
["options", "option_ids"].each_with_object({}) { |k,h| h[k] = hash[k].values_at(*idx) }
)
#=> {"id"=>"sjfdkjfd",
# "name"=>"Field Name",
# "type"=>"field",
# "options"=>["L", "Q", "A", "Q"],
# "option_ids"=>["12345", "23456", "45678", "cat"]}
Если «повторяющиеся элементы» интерпретируются как означающие, что значения "options"
и "option_ids"
должны иметь только первые три элемента, показанные выше, вычислите idx
следующим образом:
idx = hash["options"].
each_with_index.
uniq { |s,_| s }.
map(&:last)
#=> [0, 1, 4]
См. Enumerable # chunk_ while ( Enumerable # slice_when можно использоватьвместо этого) и Array # values_at .Шаги следующие:
a = hash["options"]
#=> ["L", "Q", "Q", "Q", "A", "A", "Q"]
e0 = a.each_with_index
#=> #<Enumerator: ["L", "Q", "Q", "Q", "A", "A", "Q"]:each_with_index>
e1 = e0.chunk_while { |(a,_),(b,_)| a==b }
#=> #<Enumerator: #<Enumerator::Generator:0x000055e4bcf17740>:each>
Мы можем увидеть значения, которые перечислитель e1
сгенерирует и передаст в map
, преобразовав его в массив:
e1.to_a
#=> [[["L", 0]],
# [["Q", 1], ["Q", 2], ["Q", 3]],
# [["A", 4], ["A", 5]], [["Q", 6]]]
Продолжение,
idx = e1.map { |(_,i),*| i }
#=> [0, 1, 4, 6]
c = ["options", "option_ids"].
each_with_object({}) { |k,h| h[k] = hash[k].values_at(*idx) }
#=> {"options"=>["L", "Q", "A", "Q"],
# "option_ids"=>["12345", "23456", "45678", "cat"]}
hash.merge(c)
#=> {"id"=>"sjfdkjfd",
# "name"=>"Field Name",
# "type"=>"field",
# "options"=>["L", "Q", "A", "Q"],
# "option_ids"=>["12345", "23456", "45678", "cat"]}