Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何比较共享相同内容的两个StructType?_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 如何比较共享相同内容的两个StructType?

Scala 如何比较共享相同内容的两个StructType?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,似乎StructType保留了顺序,因此包含相同StructField的两个StructType不被认为是等价的 例如: val st1 = StructType( StructField("ii",StringType,true) :: StructField("i",StringType,true) :: Nil) val st2 = StructType( StructField("i",StringType,true) :: StructField("ii",StringType,

似乎
StructType
保留了顺序,因此包含相同
StructField
的两个
StructType
不被认为是等价的

例如:

val st1 = StructType(
StructField("ii",StringType,true) :: 
StructField("i",StringType,true) :: Nil)

val st2 = StructType(
StructField("i",StringType,true) :: 
StructField("ii",StringType,true) :: Nil)

println(st1 == st2)
返回
false
,即使它们都有
StructField(“i”,StringType,true)
StructField(“ii”,StringType,true)
,只是顺序不同而已

我需要一个测试,可以说这两个是相等的,因为就我的目的而言,这两个是没有区别的

val schema1 = StructType(StructField("A",ArrayType(st1,true),true) :: Nil)

val schema2 = StructType(StructField("A",ArrayType(st2,true),true) :: Nil)

val final_schema = StructType((schema1 ++ schema2).distinct)
final\u schmea
的结果应该只有一个
A
StructType
而不是两个,但是
distinct
认为这两个
StructType
是不同的,因此我最终得到两个不同的
StructField
命名为
A
。所以我的问题是,有没有一种方法可以根据内容而不是顺序来比较两个
StructType
s

编辑:


经过进一步的调查,由于
StructType
基本上是
Seq
,我可以这样做,但我正在尝试想出一种方法,可以最有效地对嵌入式
StructType
进行比较。

这可能会被清除,但它可以工作并处理嵌套的StructType:

def isEqual(struct1: StructType, struct2: StructType): Boolean = {
  struct1.headOption match {
    case Some(field) => {
      if(field.dataType.typeName != "struct") {
        struct2.find(_ == field) match {
         case Some(matchedField) => isEqual(StructType(struct1.filterNot(_ == field)), StructType(struct2.filterNot(_ == field)))
         case None => false
        }
      } else {
        val isEqualContents = struct2.find(x => x.name == field.name && x.nullable == field.nullable && x.dataType.typeName == "struct") match {
          case Some(matchedField) => isEqual(field.dataType.asInstanceOf[StructType], matchedField.dataType.asInstanceOf[StructType])
          case None => false
        }
        if(isEqualContents) isEqual(StructType(struct1.filterNot(_ == field)), StructType(struct2.filterNot(_ == field))) else false
      }
    }
    case None => struct2.size == 0
  }
}

val st1 = StructType(
StructField("ii",StringType,true) :: 
StructField("i",StringType,true) :: 
StructField("iii", StructType(StructField("iv", StringType, true) :: Nil), true) :: Nil)

val st2 = StructType(
StructField("i",StringType,true) :: 
StructField("ii",StringType,true) :: 
StructField("iii", StructType(StructField("v", StringType, true) :: Nil), true) :: Nil)

isEqual(st1, st2)

它还可以使用更多的爱来实现尾部递归。

我将模式比较如下:

assert(structType1 == structType2, "not equal schemas")
即使在Spark的代码中,他们也使用“=”来比较结构类型

您可以在org.apache.spark.sql.sources下签出表cansuite.scala

我希望有帮助

assert(expectedSchema == spark.table("tableWithSchema").schema)