我有一个流式JSON数据,其结构可以用下面的case类描述
package edge;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.Timer;
public class Dungeon1 extends javax.swing.JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
Timer timer = new Timer(1, this);
Player player = new Player();
DungeonBackground db = new DungeonBackground(0, 0);
Enemy e1 = new Enemy(200, 200);
/**
* Creates new form Dungeon1
*/
public Dungeon1() {
initComponents();
setSize(1366, 706);
timer.start();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setBackground(new java.awt.Color(0, 0, 0));
setRequestFocusEnabled(false);
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edge/Dundeon 1 - 1.jpg"))); // NOI18N
jLabel1.setText("\n");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 707, Short.MAX_VALUE)
);
}// </editor-fold>
public void Paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
ImageIcon img = new ImageIcon("Dundeon 1 - 1.jpg");
IMG = img.getImage();
g2d.drawImage(IMG, 0, 0, null);
if (firstform == true && secondform == false && thirdform == false) {
ImageIcon imageIcon2 = new ImageIcon("enemy1.bmp");
g2d.drawImage(imageIcon2.getImage(), e1.getX(), e1.getY(), this);
} else if (secondform == true && firstform == false && thirdform == false) {
ImageIcon imageIcon3 = new ImageIcon("enemy1-1.bmp");
g2d.drawImage(imageIcon3.getImage(), e1.getX(), e1.getY(), this);
secondform = false;
thirdform = true;
firstform = false;
} else if (thirdform == true && firstform == false && secondform == false) {
ImageIcon imageIcon4 = new ImageIcon("enemy1-2.bmp");
g2d.drawImage(imageIcon4.getImage(), e1.getX(), e1.getY(), this);
firstform = true;
secondform = false;
thirdform = false;
RageGUI rg1 = new RageGUI();
rg1.setVisible(true);
}
ImageIcon imageIcon = new ImageIcon("characterfinal.jpg");
g2d.drawImage(imageIcon.getImage(), player.getX(), player.getY(), this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e1.getX() == (player.getX() + 190) && e1.getY() == player.getY()
|| e1.getY() == (player.getY() - 190) && e1.getX() == player.getX()) {
firstform = false;
secondform = true;
}
if (e1.getX() == (player.getX() - 190) && e1.getY() == player.getY()) {
firstform = false;
secondform = true;
}
if (e1.getY() == (player.getY() - 190) && e1.getX() == player.getX()) {
firstform = false;
secondform = true;
}
while (e1isalive == true) {
double rdn = Math.random();
if (rdn <= 0.25) {
e1.MoveSequence1();
}
if (rdn <= 0.5) {
e1.MoveSequence2();
}
if (rdn <= 0.75) {
e1.MoveSequence3();
}
if (rdn <= 1) {
e1.MoveSequence4();
}
}
if (player.getX() == 87 && player.getY() == 81 && player.getDirection() == 4) {
player.MoveLeft();
player.MoveDown();
}
if (player.getX() == 380 && player.getY() == 500 && player.getDirection() == 4) {
player.MoveLeft();
}
if (player.getX() == 91 && player.getY() == 520 && player.getDirection() == 4) {
player.MoveLeft();
}
if (player.getX() == 85 && player.getY()== 355 && player.getDirection() == 4) {
player.MoveLeft();
}
if (player.getX() == 284 && player.getY() == 399 && player.getDirection() == 3) {
player.MoveRight();
}
if (player.getX() == 284 && player.getY() == 399 && player.getDirection() == 1) {
player.MoveDown();
}
if (player.getX() == 649 && player.getY() == 515 && player.getDirection() == 3) {
player.MoveRight();
}
if (player.getX() == 811 && player.getY() == 243 && player.getDirection() == 2) {
player.MoveUp();
}
if (player.getX() == 811 && player.getY() == 243 && player.getDirection() == 1) {
player.MoveDown();
}
if (player.getX() == 671 && player.getY() == 365 && player.getDirection() == 4) {
player.MoveLeft();
}
if (player.getX() == 940 && player.getY() == 350 && player.getDirection() == 3) {
player.MoveLeft();
}
if (player.getX() == 812 && player.getY() == 513 && player.getDirection() == 1) {
player.MoveDown();
}
if (player.getX() == 140 && player.getY() == 150 && player.getDirection() == 4) {
player.MoveLeft();
}
if (player.getX() == 900 && player.getY() == 600 && player.getDirection() == 3 ) {
player.MoveRight();
}
if (player.getX() == 1159 && player.getY() == 461 && player.getDirection() == 3 ) {
player.MoveRight();
}
if (player.getX() == 660 && player.getY() == 110 && player.getDirection() == 4 ) {
player.MoveLeft();
}
if (player.getX() == 995 && player.getY() == 285 && player.getDirection() == 1) {
player.MoveDown();
}
if (player.getX() == 1160 && player.getY() == 120 && player.getDirection() == 3 ) {
player.MoveRight();
}
if (player.getX() == 393 && player.getY() == 634 && player.getDirection() == 4) {
System.out.println("do you want to die???"
+ " or did you think you found a secret way out of the dungeon??"
+ " well you are right, you win");
RageQuitGUI rg = new RageQuitGUI() ;
rg.setVisible(true) ;
}
repaint();
}
@Override
public void keyTyped(KeyEvent ke) {
}
@Override
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_W) {
player.MoveUp();
System.out.println("w key has been pressed");
} else if (ke.getKeyCode() == KeyEvent.VK_A) {
player.MoveLeft();
System.out.println("a key has been pressed");
} else if (ke.getKeyCode() == KeyEvent.VK_D) {
player.MoveRight();
System.out.println("d key has been pressed");
} else if (ke.getKeyCode() == KeyEvent.VK_S) {
player.MoveDown();
System.out.println("s key has been pressed");
}
if (ke.getKeyCode() == KeyEvent.VK_ALT + KeyEvent.VK_F4) {
RageQuitGUI rg = new RageQuitGUI();
rg.setVisible(true);
}
}
@Override
public void keyReleased(KeyEvent ke) {
}
boolean e1isalive = true;
boolean firstform = true;
boolean secondform = false;
boolean thirdform = false;
Image IMG;
// sometimes the code works and soetimes it doesnt.
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
// End of variables declaration
}
相同的样本数据如下
case class Hello(A: String, B: Array[Map[String, String]])
我想将其转换为
| A | B |
|-------|------------------------------------------|
| ABC | [{C:1, D:1}, {C:2, D:4}] |
| XYZ | [{C:3, D :6}, {C:9, D:11}, {C:5, D:12}] |
任何帮助将不胜感激。
答案 0 :(得分:1)
不确定最好的方法,但是可以分两步完成。抛开您的案例类,以下内容:
import org.apache.spark.sql.functions._
//case class ComponentPlacement(A: String, B: Array[Map[String, String]])
val df = Seq (
("ABC", List(Map("C" -> "1", "D" -> "2"))),
("XYZ", List(Map("C" -> "11", "D" -> "22")))
).toDF("A", "B")
val df2 = df.select($"A", explode($"B")).toDF("A", "Bn")
val df3 = df2.select($"A", explode($"Bn")).toDF("A", "B", "C")
val df4 = df3.select($"A", $"B", $"C").groupBy("A").pivot("B").agg(first($"C"))
返回:
+---+---+---+
| A| C| D|
+---+---+---+
|XYZ| 11| 22|
|ABC| 1| 2|
+---+---+---+
答案 1 :(得分:1)
随着问题的发展,我将原来的答案留在那里,这解决了最后一个问题。
重要的一点,现在满足以下要求的输入内容:
val df0 = Seq (
("ABC", List(Map("C" -> "1", "D" -> "2"), Map("C" -> "3", "D" -> "4"))),
("XYZ", List(Map("C" -> "44", "D" -> "55"), Map("C" -> "188", "D" -> "199"), Map("C" -> "88", "D" -> "99")))
)
.toDF("A", "B")
也可以这样做,但是随后需要对此脚本进行修改,尽管这很简单:
val df0 = Seq (
("ABC", List(Map("C" -> "1", "D" -> "2"))),
("ABC", List(Map("C" -> "44", "D" -> "55"))),
("XYZ", List(Map("C" -> "11", "D" -> "22")))
)
.toDF("A", "B")
然后按照要求的格式进行操作:
val df1 = df0.select($"A", explode($"B")).toDF("A", "Bn")
val df2 = df1.withColumn("SeqNum", monotonically_increasing_id()).toDF("A", "Bn", "SeqNum")
val df3 = df2.select($"A", explode($"Bn"), $"SeqNum").toDF("A", "B", "C", "SeqNum")
val df4 = df3.withColumn("dummy", concat( $"SeqNum", lit("||"), $"A"))
val df5 = df4.select($"dummy", $"B", $"C").groupBy("dummy").pivot("B").agg(first($"C"))
val df6 = df5.withColumn("A", substring_index(col("dummy"), "||", -1)).drop("dummy")
df6.show(false)
返回:
+---+---+---+
|C |D |A |
+---+---+---+
|3 |4 |ABC|
|1 |2 |ABC|
|88 |99 |XYZ|
|188|199|XYZ|
|44 |55 |XYZ|
+---+---+---+
您可以对列进行重新排序。