Scala 将键与MapType列中值数组中的第一个元素连接起来

Scala 将键与MapType列中值数组中的第一个元素连接起来,scala,dataframe,apache-spark,apache-spark-sql,Scala,Dataframe,Apache Spark,Apache Spark Sql,下面给出了数据帧的模式 |--idMap:map(nullable=true) ||--键:字符串 ||--值:数组(valuecontainsnall=true) || |--元素:struct(containsnall=true) || | |--id:string(nullable=true) || | |--linked:boolean(nullable=true) 例如,如果一行中有3个键,我将尝试将其转换为格式为key1:id;键2:id;键3:id其中id是索引0处元素的一部分

下面给出了数据帧的模式

|--idMap:map(nullable=true)
||--键:字符串
||--值:数组(valuecontainsnall=true)
|| |--元素:struct(containsnall=true)
|| | |--id:string(nullable=true)
|| | |--linked:boolean(nullable=true)
例如,如果一行中有3个键,我将尝试将其转换为格式为
key1:id;键2:id;键3:id
其中id是索引0处元素的一部分

我试过的是

  • 收集列表的键
  • 从键列表创建列列表
  • 添加一个新列,其中包含传递给concat的列列表
  • 它给了我一个空列,所以我认为这种方法是有缺陷的。如有任何意见,将不胜感激

    编辑:@mck的答案有效。在第3步中使用concat_ws也同样有效

    val finalDf = df.withColumn("concatColumn", concat_ws(expr.toList:_*))
    

    如果您有Spark 3,则可以使用
    transform\u值
    来变换贴图列以获得所需的输出

    // sample dataframe
    val df = spark.sql("select map('key1', array(struct('id1' id, true linked)), 'key2', array(struct('id2' id, false linked))) idMap")
    
    val df2 = df.withColumn(
        "concatColumn", 
        expr("""
            concat_ws(';', 
                map_values(
                    transform_values(
                        idMap, 
                        (k, v) -> concat(k, ':', transform(v, y -> y.id)[0])
                    )
                )
            ) 
        """)
    )
    
    df2.show(false)
    +-----------------------------------------------+-----------------+
    |idMap                                          |concatColumn     |
    +-----------------------------------------------+-----------------+
    |[key1 -> [[id1, true]], key2 -> [[id2, false]]]|key1:id1;key2:id2|
    +-----------------------------------------------+-----------------+
    
    val finalDf = df.withColumn("concatColumn", concat_ws(expr.toList:_*))
    
    // sample dataframe
    val df = spark.sql("select map('key1', array(struct('id1' id, true linked)), 'key2', array(struct('id2' id, false linked))) idMap")
    
    val df2 = df.withColumn(
        "concatColumn", 
        expr("""
            concat_ws(';', 
                map_values(
                    transform_values(
                        idMap, 
                        (k, v) -> concat(k, ':', transform(v, y -> y.id)[0])
                    )
                )
            ) 
        """)
    )
    
    df2.show(false)
    +-----------------------------------------------+-----------------+
    |idMap                                          |concatColumn     |
    +-----------------------------------------------+-----------------+
    |[key1 -> [[id1, true]], key2 -> [[id2, false]]]|key1:id1;key2:id2|
    +-----------------------------------------------+-----------------+