Scala 3,ADT,组合集合中的元素

问题描述 投票:0回答:1

我是 Scala 新手,正在尝试使用 Scala 3 枚举作为 ADT,并且我有一个集合,我试图通过以下方式“减少”:

enum Stats:
    case MaximumHealth(val x: Float)
    case HealthRegen(val x: Float)

def combineStats: Array[Stats] =
    val startWith = Array(Stats.MaximumHealth(20), Stats.MaximumHealth(10), Stats.HealthRegen(5))

    // how can I iterate/recurse over 'startWith' and "combine" multiple stats 
    // (such as MaximumHealth) entries into one?
    // (ie, producing endWith below)?

    val endWith = Array(Stats.MaximumHealth(30), Stats.HealthRegen(5))
    endWith

我该怎么做?经常建议使用 GroupBy,但我不知道如何仅按枚举情况进行分组,而不使用使 Stats.MaximumHealth(20) 和 Stats.MaximumHealth(10) 不同的组的参数值。

scala algebraic-data-types
1个回答
0
投票

这是一个想法:


def combineStats(stats: Array[Stats]): Array[Stats] =
    // use `Option` to keep track of totals so we know if the input array
    // included a particular `Stats` type or not
    var maxes: Option[MaximumHealth] = None
    var regens: Option[HealthRegen] = None
    
    // loop over the input array
    stats foreach {
        case m @ MaximumHealth(h) =>
            maxes match

                case Some(MaximumHealth(t)) => maxes = Some(MaximumHealth(t + h))
                // if we haven't seen this stat type before, initialize the Option
                case _ => maxes = Some(m)
        case h @ HealthRegen(r) =>
            regens match
                case Some(HealthRegen(t)) => regens = Some(HealthRegen(t + r))
                case _ => regens = Some(h)
    }
        
    var ret: List[Stats] = Nil
    regens foreach { r => ret = r :: ret }
    maxes foreach { m => ret = m :: ret }
    
    ret.toArray

它可能看起来比必要的更复杂一点,但我想确保结果数组仅包含原始数组中存在的

Stats
类型,如果不需要,可以稍微简化。

© www.soinside.com 2019 - 2024. All rights reserved.