2016-12-29 67 views
0

看起来好像StructType保留了订单,所以包含相同StructField的两个StructType不被视为等同。如何比较两个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_schmea结果只能有A,而不是两个一个StructType,但distinct认为这两个StructType不同的,所以我最终得到两个不同的StructField命名为A。所以我的问题是,有没有办法根据它们的内容比较两个StructType S,没有订单?

编辑:

经过进一步调查,因为StructType基本上是Seq<StructField>,我可以做content comparison for that works for Seq,但我试图想办法为嵌入式StructType最有效的,我可以做对比。

回答

0

这或许可以被清理,但它的工作原理,并处理嵌套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) 

它也可以使用多一点的爱,成为尾递归了。

相关问题