2013-02-13 3 views
0

я следующие карты определенногоЯ хочу, чтобы объединить две карты в одной комбинированной карте

def Map1 = [ 
      Rate: 0, 
      Exceptions: [ Exceptions: [ [:] ] 
      ] 
def Map2 = [ 
      Exceptions: [Exceptions: [ [:] ] ] 
      ] 

map1 уже есть данные

Map1 = [ 
     Rate: 0, 
     Exceptions: [ 
         Exception: [ 
            [Code: 5, Message: "Error"], 
            [Code: 65, Message: "Error"], 
            [Code: 35, Message: "Error"] 
         ] 
     ] 
     ] 

и я хочу, чтобы добавить map2 к map1

Map2 = [ 
      Exceptions: [ 
         Exception: [ 
            [Code: 6, Message: "Error"], 
            [Code: 25, Message: "Error"], 
            [Code: 15, Message: "Error"] 
         ] 
      ] 
      ] 

Я знаю, что смогу

Map2.Exceptions.Exception.each{ Exception -> 
    Map1.Exceptions.Exception.add(Exception) 
} 

но есть ли способ сделать Groovy? то есть Map1.merge(Map2)

Редактировать: В результате я создал метод метакласса для обработки слияния. Он рекурсивный и не обрабатывает любые переменные Map/List, которые уже существуют, но он делает то, что мне нужно.

Map.metaClass.Merge = { Map Source -> 
     Map Destination = delegate 
     Source.keySet().each{ key -> 
      if(Destination.keySet().contains(key)){ 
       if(!(Source[key] instanceof Map)){ 
        if(Source[key] instanceof List){ 
         Source[key].each{ Value -> 
          Destination[key].add(Value) 
         }//Source[Key].each 
        }//if(Source[key] instanceof List) 
       }//if(!(Source[key] instanceof Map)) 
       else{ 
        Destination[key].Merge(Source[key]) 
       }//else(!(Source[key] instanceof Map)) 
      }//if(Destination.keySet().contains(key)) 
      else{ 
       Destination[key] = Source[key] 
      }//else(Destination.keySet().contains(key)) 
     }//Source.keySet().each 
    }//Map.metaclass.Merge(Map Source) 
+2

Не то, что я знаю, как это очень сильно зависит от структуры ваших карт и функциональность вы хотите. Самое близкое, что вы можете получить, это '(map1 as ConfigObject) .merge (map2 as ConfigObject)', но это не те функции, которые вам нужны, поскольку значение map2 'Exception' необходимо добавить в список исключений map1, а не переписывать его как и по умолчанию –

ответ

1

Может быть, так?

Map1.Exceptions.Exception += Map2.Exceptions.Exception 
print Map1 

Выход:

[Rate:0, Exceptions:[Exception:[[Code:5, Message:Error], [Code:65, Message:Error], [Code:35, Message:Error], [Code:6, Message:Error], [Code:25, Message:Error], [Code:15, Message:Error]]]] 
+0

Желание Я видел ваш ответ, прежде чем я начал работать над методом расширения класса карты. Ну что ж. Спасибо хоть. –

+0

Ну, мой ответ работает только в этом конкретном случае. Например Map1.Exceptions + = Map2.Exceptions не будут работать, потому что они будут содержать только элементы Map2.Exceptions. Если вы можете гарантировать, что структура всегда будет выглядеть в вашем примере, мой ответ будет работать, но так будет и ваше закрытие. Так что, может быть, вы ничего не сделали всю работу :) – Fels

+0

Если я не ошибаюсь, это будет работать только на первом уровне структуры карты. В случае вложенных структур, когда вторая карта заполнена только частично, этот подход потерпит неудачу. [foo: 'aaa', bar: [buzz: 'bbb', qux: 'ccc']] + [bar: [buzz: 'ddd]] == [foo: aaa, bar: [buzz:' ddd ' ]] – pseudo