首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归地列出无形状的空字段

递归地列出无形状的空字段
EN

Stack Overflow用户
提问于 2022-03-22 18:45:13
回答 1查看 81关注 0票数 2

我试图递归地列出不成形的空字段。但它似乎并没有显示所有的字段:

https://scastie.scala-lang.org/PtLdSRC2Qfipu054Hzerrw

代码语言:javascript
复制
import shapeless._
import shapeless.labelled.FieldType

trait NullFields[T] {
  def apply(value: T, parent: String): Seq[String]
}

object NullFields extends NullFieldsLowPriority {
  implicit lazy val hNil = new NullFields[HNil] {
    override def apply(value: HNil, parent: String) = Seq.empty
  }

  implicit def hConsOption[K <: Symbol, V, TailFields <: HList](implicit
      witness: Witness.Aux[K],
      tailNullFields: NullFields[TailFields]
  ) = new NullFields[FieldType[K, Option[V]] :: TailFields] {
    override def apply(
        params: FieldType[K, Option[V]] :: TailFields,
        parent: String
    ) =
      (if (params.head.isEmpty) Seq(parent + witness.value.name)
       else Seq.empty) ++
        tailNullFields(params.tail, parent)
  }

  implicit def hConsCaseClass[
      K <: Symbol,
      CC <: Product,
      Fields <: HList,
      TailFields <: HList
  ](implicit
      generic: LabelledGeneric.Aux[CC, Fields],
      nullFields: NullFields[Fields],
      witness: Witness.Aux[K],
      tailNullFields: NullFields[TailFields]
  ) = new NullFields[FieldType[K, CC] :: TailFields] {
    override def apply(params: FieldType[K, CC] :: TailFields, parent: String) =
      nullFields(generic.to(params.head), s"$parent${witness.value.name}.") ++
        tailNullFields(params.tail, parent)
  }

  implicit def caseClass[CC, Fields <: HList](implicit
      generic: LabelledGeneric.Aux[CC, Fields],
      nullFields: NullFields[Fields]
  ) = new NullFields[CC] {
    override def apply(value: CC, parent: String) =
      nullFields(generic.to(value), parent)
  }
}

trait NullFieldsLowPriority {
  implicit def hConsDefault[K <: Symbol, V, TailFields <: HList](implicit
      tailNullFields: NullFields[TailFields]
  ) = new NullFields[FieldType[K, V] :: TailFields] {
    override def apply(params: FieldType[K, V] :: TailFields, parent: String) =
      tailNullFields(params.tail, parent)
  }
}

case class B(
    balba: Int = 0,
    profile_experience_desc: Option[String] = None,
    vmaf: Va
)
case class Va(
    tw_segment: Option[Double],
    i20_segment: Option[Double],
    ttq_segment: Option[Int]
)

println(implicitly[NullFields[B]].apply(B(vmaf = Va(None, None, None)), ""))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-23 02:58:46

我不确定这正是你想要的,但我希望你能调整它,使它符合你的需要。我认为以下内容是null的:

  • 所有Nones
  • 任何其他类型的null
  • 递归nullNone在case类和/或Option中找到

您可以添加更多的implicits来处理其他情况:

代码语言:javascript
复制
import shapeless._
import shapeless.labelled.FieldType

trait NullFields[T] {
  def apply(value: T, parent: String): Seq[String]
}

object NullFields extends LowPrioriyImplicits {
  def apply[A](implicit nullFields: NullFields[A]): NullFields[A] = nullFields
  
  implicit class NullFieldsOps[A](a: A) {
    def nulls(implicit ev: NullFields[A]) = NullFields[A].apply(a, "")
  }

  implicit def option[V](implicit nullFields: NullFields[V]): NullFields[Option[V]] =
    (option: Option[V], parent: String) => 
      if (option.isEmpty) Seq(parent)
      else nullFields(option.head, parent)

  implicit def caseClass[CC, Fields <: HList](implicit
      generic: LabelledGeneric.Aux[CC, Fields],
      nullFields: NullFields[Fields]
  ): NullFields[CC] = (value: CC, parent: String) => nullFields(generic.to(value), parent)

  implicit def hCons[K <: Symbol, Field, TailFields <: HList](implicit
      witness: Witness.Aux[K],
      nullFields: Lazy[NullFields[Field]],
      tailNullFields: Lazy[NullFields[TailFields]]
  ): NullFields[FieldType[K, Field] :: TailFields] =
    (params: FieldType[K, Field] :: TailFields, parent: String) =>
      nullFields.value(params.head, (if (parent.isEmpty) "" else s"$parent.") + witness.value.name) ++
        tailNullFields.value(params.tail, parent)

  implicit val hNil: NullFields[HNil] = (value: HNil, parent: String) => Seq.empty
}

trait LowPrioriyImplicits {
  implicit def other[A]: NullFields[A] =
    (value: A, parent: String) => if (value == null) Seq(parent) else Seq.empty
}

相同的Scastie链接

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71577406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档