2017-04-05 50 views
1

我有一個看起來像這兩數組列表,(這我要簡化這個問題):的Groovy - ArrayList的一個遞增項目數量,而不是重新添加

def originalList = [[name: "Ben", age: 21, weight: 80], [name: "Martin", age: 36, weight: 99], [name: "Sammy", age: 18, weight: 65], [name: "Ben", age: 28, weight: 75], [name: "Ben", age: 28, weight: 120]] 

另一位我會請撥打newList並開始爲空,即def newList = [],但會添加屬性name,ageoccurrences

現在我想做的是循環遍歷originalList,並添加其項目newList但如果newList已經包含具有相同名稱年齡屬性的項目我想遞增occurrences屬性的項目,如:

def newList = [[name: "Ben", age: 21, occurrences: 1], [name: "Martin", age: 36, occurrences: 1], [name: "Sammy", age: 18, occurrences: 1], [name: "Ben", age: 28, occurrences: 2]] 

我該如何着手完成這項工作?這是我嘗試過的。

originalList.each { 
    newList.eachWithIndex { nl, i -> 
     if(nl.name.equals(it.name) && nl.age == it.age) { 
      nl.occurrances++ 
     } else { 
      newList.add([name: it.name, age: it.age, occurrances: 0]) 
     } 
    } 
} 

它看起來像它不工作怎麼把newList.eachWithIndex永遠循環怎麼把它開始是空的,怎麼把它永遠循環可以永遠遞增occurrences財產或項目添加到列表中。

回答

3

你可以這種方式例如:

def originalList = [ 
    [name: "Ben", age: 21, weight: 80], 
    [name: "Martin", age: 36, weight: 99], 
    [name: "Sammy", age: 18, weight: 65], 
    [name: "Ben", age: 28, weight: 75], 
    [name: "Ben", age: 28, weight: 120] 
] 

originalList 
    .groupBy({ it.name }, { it.age }) 
    .collect { k1, v1 -> v1.collect { k2, v2 -> [name: k1, age: k2, occurrences: v2.size()] } } 
    .flatten() 

它的第一步驟的輸入被兩個name分組並age這導致Map,然後valuesv1)每個鍵​​被處理獲取統計信息。由於上述操作導致嵌套List,所以在最後調用flatten()

+1

或者只需通過將您感興趣的k/v集合分組即可擺脫第一層即可:'originalList.groupBy {it.subMap(「name」,「age」)}。collect {k,os-> k + [occurrences: os.size()]}' – cfrick

+0

@cfrick,很好!你是否每天都與groovy合作? – Opal

+1

或'originalList.groupBy {「$ it.name :: $ it.age」} .values()。collect {it.head()+ [occurrences:it.size()]}' –

-1

我不是一個時髦的開發人員,所以我會在java中編寫代碼片段。請翻譯你自己。

Map<String,Integer> map=new HashMap<String,Integer>();//this map stores name and occurances 

for(Employee e: originaleList){ 
    int oldCount=map.get(e.getName()) == null ? 0 : map.get(e.getName()); 
    map.put(e.getName(), oldCount + 1); 

    newList.add(new Employee(e.getName(), e.getAge(), map.get(e.getName()))); 
    } 
1

只是在你原來的算法修復的bug(使用地圖的方式更有效,雖然!):

originalList.each { 
    def found=false 
    newList.eachWithIndex { nl, i -> 
     if(nl.name.equals(it.name) && nl.age == it.age) { 
      nl.occurrances++ 
      found = true 
     } 
    } 
    if (!found) { 
     newList.add([name: it.name, age: it.age, occurrances: 1]) 
    } 
} 

UPDATE:版本地圖,根據要求...

def map = [:] 

originalList.each { 
    def key = it.name+"@"+it.age // or something better, keeping it simple here 

    if (map[key]) { 
     map[key].occurances++ 
    } 
    else { 
     def entry = [name: it.name, age: it.age, occurrances: 1] 
     map[key] = entry 
     newList.add(entry) 
    } 
}  
+0

hashmap version上面的樣子?如果你不介意把它添加到你的答案? – PrintlnParams

相關問題