如何遍历地图并在有匹配值的情况下仅显示一行

时间:2019-04-24 04:48:45

标签: groovy

我有一个具有不同键和多个值的映射。如果在不同键之间有任何匹配的作业,则我只需要显示一行并分组代码值。

def data = ['Test1':[[name:'John',dob:'02/20/1970',job:'Testing',code:51],[name:'X',dob:'03/21/1974',job:'QA',code:52]],
            'Test2':[name:'Michael',dob:'04/01/1973',job:'Testing',code:52]]

for (Map.Entry<String, List<String>> entry : data.entrySet()) {
    String key = entry.getKey();
    List<String> values = entry.getValue();
    values.eachWithIndex{itr,index->
        println("key is:"+key);
        println("itr values are:"+itr);
    }
}

预期结果:[job:Testing,code:[51,52]]

3 个答案:

答案 0 :(得分:2)

您可以使用Groovy的收集方法。

首先,您需要提取列表,因为您不需要顶级元素的键

def jobs = data.values()

然后,您可以使用groupBy方法按“作业”键进行分组

def groupedJobs = jobs.groupBy { it.job }

上面的代码将在您的示例中产生以下结果

[Testing:[[name:John, dob:02/20/1970, job:Testing, code:51], [name:Michael, dob:04/01/1973, job:Testing, code:52]]]

现在,您只能通过以下收集功能获取代码作为值,并进行适当的更改以使密钥作为工作

def result = groupedJobs.collect {key, value ->
   [job: key, code: value.code] 
}

答案 1 :(得分:2)

以下代码(使用您的示例数据集):

def data = ['Test1':[name:'John',    dob:'02/20/1970', job:'Testing', code:51],
            'Test2':[name:'Michael', dob:'04/01/1973', job:'Testing', code:52]]

def matchFor  = 'Testing'

def result = [job: matchFor, code: data.findResults { _, m -> 
  m.job == matchFor ? m.code : null
}]

println result

结果:

~> groovy solution.groovy
[job:Testing, code:[51, 52]]

~> 

运行时。它使用groovy Map.findResults方法从匹配的作业中收集代码。

答案 2 :(得分:2)

首先将所有相关地图展平,因此只对它们进行平展,然后与其他建议的地图基本相同:按工作分组并保留代码(通过传播算子)

def data = ['Test1':[[name:'John',dob:'02/20/1970',job:'Testing',code:51],[name:'X',dob:'03/21/1974',job:'QA',code:52]], 'Test2':[name:'Michael',dob:'04/01/1973',job:'Testing',code:52]]

assert data.values().flatten().groupBy{it.job}.collectEntries{ [it.key, it.value*.code] } == [Testing: [51, 52], QA: [52]]

注意:问题将根据其他答案的评论而改变。

以上代码将为您提供工作及其代码。

到目前为止,尚不清楚新的预期输出是什么。