筛选具有多个条件的列表

时间:2018-08-02 17:33:17

标签: java-8 kotlin higher-order-functions

我有一个类似于以下的数据结构:

[{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中的示例实现(伪代码)。

4 个答案:

答案 0 :(得分:5)

由于您没有提供起始代码,因此我将您的数据转换为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)]

答案 1 :(得分:1)

如果我可以借用zsmb13的声明,则可以通过以下方式产生相同的结果:

val highestOfEachFeature = options
        .sortedByDescending { it.score }
        .distinctBy { it.feature }

答案 2 :(得分:1)

除了zsmb13的正确答案外,我想使用property referencesdestructuring declarations提出更简洁的语法:

val highestOfEachFeature = options
    .groupBy(Item::feature)
    .map { (_, list) -> list.maxBy(Item::score) }

答案 3 :(得分:0)

即使Kotlin语法更简洁明了,如果您想按一个键分组并将聚合函数应用于该组中的值,也可以使用Java 8。

这是一个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]}