gpt4 book ai didi

scala - 寻找一个处理平局(即相等值)的 FP 排名实现

转载 作者:行者123 更新时间:2023-12-03 04:52:48 24 4
gpt4 key购买 nike

从值的排序序列开始,我的目标是为每个值分配一个排名,对相等的值使用相同的排名(也称为平局):

输入:向量(1, 1, 3, 3, 3, 5, 6)

输出:向量((0,1), (0,1), (1,3), (1,3), (1,3), (2,5), (3,6 ))

一些类型别名以提高可读性:

type Rank = Int
type Value = Int
type RankValuePair = (Rank, Value)

使用可变 rank 变量的命令式实现可能如下所示:

var rank = 0
val ranked1: Vector[RankValuePair] = for ((value, index) <- values.zipWithIndex) yield {
if ((index > 0) && (values(index - 1) != value)) rank += 1
(rank, value)
}

// ranked1: Vector((0,1), (0,1), (1,3), (1,3), (1,3), (2,5), (3,6))

为了磨练我的 FP 技能,我试图提出一个功能实现:

val ranked2: Vector[RankValuePair] = values.sliding(2).foldLeft((0 , Vector.empty[RankValuePair])) {
case ((rank: Rank, rankedValues: Vector[RankValuePair]), Vector(currentValue, nextValue)) =>
val newRank = if (nextValue > currentValue) rank + 1 else rank
val newRankedValues = rankedValues :+ (rank, currentValue)
(newRank, newRankedValues)
}._2

// ranked2: Vector((0,1), (0,1), (1,3), (1,3), (1,3), (2,5))

它的可读性较差,而且更重要的是缺少最后一个值(由于在奇数个值上使用 sliding(2))。

如何解决和改进这个问题?

最佳答案

这对我来说很有效:

// scala
val vs = Vector(1, 1, 3, 3, 3, 5, 6)
val rank = vs.distinct.zipWithIndex.toMap
val result = vs.map(i => (rank(i), i))

在 Java 8 中使用 Javaslang 也是如此:

// java(slang)
Vector<Integer> vs = Vector(1, 1, 3, 3, 3, 5, 6);
Function<Integer, Integer> rank = vs.distinct().zipWithIndex().toMap(t -> t);
Vector<Tuple2<Integer, Integer>> result = vs.map(i -> Tuple(rank.apply(i), i));

两种变体的输出是

Vector((0, 1), (0, 1), (1, 3), (1, 3), (1, 3), (2, 5), (3, 6))

*) 披露:我是 Javaslang 的创建者

关于scala - 寻找一个处理平局(即相等值)的 FP 排名实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40373066/

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