2016-08-11 2 views
0

I имеет массив хэшСписок групп хэш и индексировать значения

Некоторых хэш дубликат

Я хочу, чтобы сохранить копию, но добавить счетчика к названию

Например «TITLE # 1" и "TITLE # 2"

Это мой массив

list = [] 
@temp = {} 
@temp["name"] = "Germany" 
@temp["id"] = 1 
list << @temp 

@temp["name"] = "USA" 
@temp["id"] = 2 
list << @temp 

@temp["name"] = "USA" 
@temp["id"] = 3 
list << @temp 

@temp["name"] = "France" 
@temp["id"] = 4 
list << @temp 

@temp["name"] = "France" 
@temp["id"] = 5 
list << @temp 

@temp["name"] = "France" 
@temp["id"] = 6 
list << @temp 

I Want результат Аналогично источнику, но рядом с «США» добавить счетчик «США №1» и «США № 2» И Франция перейдет на «Франция №1», «Франция № 2» «Франция № 3»

Никаких изменений в германии нет, потому что нет нескольких предметов.

+0

В приведенном примере содержится ошибка. Обновляя '@ temp' вместо того, чтобы переустановить новый хеш для каждой новой записи, вы добавляете в свой список элементы, которые ссылаются на один и тот же хэш в памяти. Это приводит к тому, что ваш список выглядит как 6 элементов для '{" name "=>" France "," id "=> 6}' – Keith

+0

Этот вопрос касается манипуляции массивом 'list', а не как' list' построен. Поэтому я предлагаю вам заменить ваш код на «list» после выполнения вычислений, как показано в моем ответе. Как правило, когда вы приводите пример, присвойте переменную каждому входному объекту (например, 'list = [...]'). Таким образом, читатели могут ссылаться на эти переменные в ответах и ​​комментариях, не определяя их. Также покажите желаемый результат, который представляет собой массив, показанный в моем ответе. –

ответ

0

Вам нужно @temp = 0 в начале каждого блока кода.

После выполнения кода с модификацией

list = [{"name"=>"Germany", "id"=>1}, 
     {"name"=>"USA", "id"=>2}, 
     {"name"=>"USA", "id"=>3}, 
     {"name"=>"France", "id"=>4}, 
     {"name"=>"France", "id"=>5}, 
     {"name"=>"France", "id"=>6}] 

Затем мы можем получить желаемый результат следующим образом.

list.group_by { |h| h["name"] }.values.flat_map do |a| 
    a.map.with_index(1) do |h,i| 
    base = h["name"] 
    h.merge("name"=>base +" #{i}") 
    end 
end 
    #=> [{"name"=>"Germany 1", "id"=>1}, 
    # {"name"=>"USA 1", "id"=>2}, 
    # {"name"=>"USA 2", "id"=>3}, 
    # {"name"=>"France 1", "id"=>4}, 
    # {"name"=>"France 2", "id"=>5}, 
    # {"name"=>"France 3", "id"=>6}] 

Примечание

arr = list.group_by { |h| h["name"] }.values 
    #=> [[{"name"=>"Germany", "id"=>1}], 
    # [{"name"=>"USA", "id"=>2}, {"name"=>"USA", "id"=>3}], 
    # [{"name"=>"France", "id"=>4}, {"name"=>"France", "id"=>5}, 
    #  {"name"=>"France", "id"=>6}]] 

Если бы я использовал Enumerable#map, а не Enumerable#flat_map, результат был бы

[[{"name"=>"Germany 1", "id"=>1}], 
    [{"name"=>"USA 1", "id"=>2}, {"name"=>"USA 2", "id"=>3}], 
    [{"name"=>"France 1", "id"=>4}, {"name"=>"France 2", "id"=>5}, 
    {"name"=>"France 3", "id"=>6}]] 

Использование flat_map эквивалентно вставив восклицательный знак перед каждой из этого массива элементы.

[*[{"name"=>"Germany 1", "id"=>1}], 
    *[{"name"=>"USA 1", "id"=>2}, {"name"=>"USA 2", "id"=>3}], 
    *[{"name"=>"France 1", "id"=>4}, {"name"=>"France 2", "id"=>5}, 
    {"name"=>"France 3", "id"=>6}]] 
Смежные вопросы