gpt4 book ai didi

java - 使用 Java lambdas 累积答案数

转载 作者:行者123 更新时间:2023-11-29 05:02:31 24 4
gpt4 key购买 nike

我有表单数据条目列表,每个 DataEntry包含类型为 Map<String, Object> 的数据字段.字符串键是动态字段名称(调查问题),值是针对该特定问题回答的选项。

在列表之外,我如何计算每个字段名称(问题)的唯一答案,我假设是这样的? Map<String, LinkedTreeMap<String, Integer> ,其中外层map key为fieldXXXX,其value map key(string)为唯一答案,key Integer为该答案的个数

出于测试目的,它们从数据库中以字符串的形式出现,我将其映射到 DTO,其中映射器映射到正确的 json 映射:

DataEntry entry1 = new DataEntry();
entry1.setData("{field9294: '4', field9296: '3', field9319: '5', field9321: '5', field9323: '3', field9325: '3', field9327: '5', field9329: '7'}");
DataEntry entry2 = new DataEntry();
entry2.setData("{field9294: '3', field9296: '2', field9319: '3', field9321: '3', field9323: '5', field9325: '2', field9327: '4', field9329: '4'}");
DataEntry entry3 = new DataEntry();
entry3.setData("{field9294: '5', field9296: '5', field9319: '4', field9321: '4', field9323: '3', field9325: '3', field9327: '4', field9329: '8'}");

List<DataEntry> dataEntries = Arrays.asList(entry1, entry2, entry3);

List<FormDataDTO> dtos = dataEntries.stream().map(mapper::dataEntryToDto).collect(Collectors.toList());

所以dtos的列表是这样的:

DTO list

最终目标

让我们以第一个字段 field9294 为例,在 3 个数据条目中给出了 3 个唯一的答案:4、3、5。这里所有的计数都应该为 1。现在 field9327 有答案 5、4、4。这里我们数 5 一次,4 两次。

一般的想法是分别绘制每个问题的数据,这样我就可以画一个图表并将结果装饰为例如百分比。

如我所见,然后得到 Map<String, LinkedTreeMap<String, Integer>足以实现这一目标,但是有没有什么有效的方法可以使用花哨的 lambda 技巧,因为我自己也搞不清楚。对于结果,我期望是这样的:

Map
key: "field9294"
values: "4" -> 1
"3" -> 1
"5" -> 1
key: "field9327"
values: "5" -> 1
"4" -> 2

等..

提前致谢!

编辑:全部通过,感谢解决方案!

assertEquals("[3=1, 4=1, 5=1]", answerCountsByField.get("field9294").entrySet().toString());
assertEquals("[2=1, 3=1, 5=1]", answerCountsByField.get("field9296").entrySet().toString());
assertEquals("[3=1, 4=1, 5=1]", answerCountsByField.get("field9319").entrySet().toString());
assertEquals("[3=1, 4=1, 5=1]", answerCountsByField.get("field9321").entrySet().toString());
assertEquals("[3=2, 5=1]", answerCountsByField.get("field9323").entrySet().toString());
assertEquals("[2=1, 3=2]", answerCountsByField.get("field9325").entrySet().toString());
assertEquals("[4=2, 5=1]", answerCountsByField.get("field9327").entrySet().toString());
assertEquals("[4=1, 7=1, 8=1]", answerCountsByField.get("field9329").entrySet().toString());

编辑2:也在寻找这种结构的解决方案。对于结果,我只关心正确的答案,错误对于绘图来说是多余的,因为这个结构映射到复选框列表

{"field6696":{"1":true,"2":true},"field7994":{"1":true,"2":false,"3":false,"4":true}}
{"field6696":{"1":false,"2":true},"field7994":{"1":false,"2":true,"3":true}}
{"field6696":{"1":false,"2":true},"field7994":{"1":false,"2":true,"3":false,"4":true}}
{"field6696":{"1":false,"2":true,"3":true},"field7994":{"1":true,"2":true,"3":false}}
{"field6696":{"1":false,"2":true},"field7994":{"1":true,"2":true,"3":true,"4":true}}

最佳答案

您应该从 Stream 开始,这样我会避免将 FormDataDTO 对象收集到 List 中。改变这个:

List<FormDataDTO> dtos = dataEntries.stream().map(mapper::dataEntryToDto).collect(Collectors.toList());

仅此而已:

Stream<FormDataDTO> dtos = dataEntries.stream().map(mapper::dataEntryToDto);

然后您可以使用 groupingBy 调用收集它们,该调用本身使用另一个收集器来创建 Map 值:

Map<String, Map<String, Long>> answerCountsByField =
dtos.flatMap(dto -> dto.getData().entrySet().stream()).collect(
Collectors.groupingBy(e -> e.getKey(),
Collectors.groupingBy(e -> e.getValue(),
Collectors.counting())));

如果您希望计数是整数而不是长整数,您可以使用 collectingAndThen 来转换每个长值:

Map<String, Map<String, Integer>> answerCountsByField =
dtos.flatMap(dto -> dto.getData().entrySet().stream()).collect(
Collectors.groupingBy(e -> e.getKey(),
Collectors.groupingBy(e -> e.getValue(),
Collectors.collectingAndThen(
Collectors.counting(), Long::intValue))));

关于java - 使用 Java lambdas 累积答案数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31626790/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com