过滤具有多个条件的列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤具有多个条件的列表相关的知识,希望对你有一定的参考价值。
我有一个类似于这样的数据结构:
[{option : {some object A},
feature : "some string value",
score : 0.9
},
{option : {some object B},
feature : "some other string value",
score : 0.9
},
{option : {some object C},
feature : "some string value",
score : 0.6
},{option : {some object D},
feature : "some string value",
score : 1.0
}]
我想过滤具有独特功能的选项。如果功能相同,我想拿一个得分最高的那个。对于上面的例子,预期结果将是:
[{option : {some object B},
feature : "some other string value",
score : 0.9
},{option : {some object D},
feature : "some string value",
score : 1.0
}]
Kotlin / Java 8中的示例实现(伪代码)表示赞赏。
答案
由于您没有提供起始代码,我将您的数据转换为Kotlin,例如:
data class Item(val feature: String, val score: Double)
val options = listOf(
Item("some string value", 0.9),
Item("some other string value", 0.9),
Item("some string value", 0.6),
Item("some string value", 1.0)
)
你需要的只是groupBy
函数,其余的很简单:
val highestOfEachFeature = options
.groupBy { it.feature }
.map { it.value.maxBy { it.score } }
结果如下:
[Option(feature=some string value, score=1.0), Option(feature=some other string value, score=0.9)]
另一答案
如果我可以借用zsmb13的声明,可以通过以下方式产生相同的结果:
val highestOfEachFeature = options
.sortedByDescending { it.score }
.distinctBy { it.feature }
另一答案
添加到zsmb13的正确答案,我想使用property references和destructuring declarations提出更简洁的语法:
val highestOfEachFeature = options
.groupBy(Item::feature)
.map { (_, list) -> list.maxBy(Item::score) }
另一答案
如果要按一个键分组并将聚合函数应用于组中的值,也可以使用Java 8,即使Kotlin具有更好,更简洁的语法。
这是一个Java 8示例:
public static void main(String[] args) {
List<Item> items = Arrays.asList(new Item("car", 2.1), new Item("car", 1.1),
new Item("bus", 3.1), new Item("bus", 4.2), new Item("motorbike", 4.6));
Map<String, Optional<Double>> collect = items.stream().collect(Collectors.groupingBy(
Item::getVal,
Collectors.mapping(Item::getScore, Collectors.maxBy(Double::compare))));
System.out.println(collect);
}
static class Item {
String val;
double score;
Item(String val, double score) {
this.val = val;
this.score = score;
}
String getVal() { return val; }
double getScore() { return score; }
}
如果您执行此代码,您将在控制台上看到:
{motorbike=Optional[4.6], bus=Optional[4.2], car=Optional[2.1]}
以上是关于过滤具有多个条件的列表的主要内容,如果未能解决你的问题,请参考以下文章