2017-04-05 27 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

相关问题