2016-12-29 65 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) 

它也可以使用多一點的愛,成爲尾遞歸了。

相關問題