usando Java para analizar un csv y luego guardarlo en una matriz 2D

Bien, entonces estoy trabajando en un juego basado en un juego de cartas coleccionables en Java. Recorté toda la "información" de las partes del juego en un archivo csv donde cada fila es una parte del juego y cada columna es un tipo de atributo para esa parte. He pasado horas y horas escribiendo código con Buffered reader, etc., tratando de extraer la información de mi archivo csv en una matriz 2D, pero fue en vano. Mi archivo CSV está vinculado aquí: http://dl.dropbox.com/u/3625527/MonstersFinal.csv Tengo un año de informática en mi haber, pero aún no puedo entender cómo hacerlo.

Entonces, mi pregunta principal es ¿cómo coloco esto en una matriz 2D para poder mantener las filas y columnas?

Respuesta 1

Bueno, como se mencionó anteriormente, algunas de sus cadenas contienen comas, por lo que inicialmente está comenzando desde un mal lugar, pero tengo una solución y es esta:

  1. --------- Si es posible, reorganice el sitio, pero realice una operación de codificación simple cuando lo haga. Querrá hacer algo como lo que notará que tiende a hacerse en archivos XML autogenerados que contienen HTML; reserve un 'carácter de control' (un carácter imprimible funciona mejor aquí, por razones de depuración y ... bueno ... cordura) que, una vez codificado, nunca debe leerse directamente como una instancia de sí mismo. Ampersand es lo que me gusta usar porque es bastante poco común pero aún imprimible, pero realmente el personaje que quieras usar depende de ti. Lo que debería hacer es escribir el programa de modo que, en cada instancia de ",", esa coma sea reemplazada por "& c" antes de ser escrita en el archivo CSV, y en cada instancia de un signo real en el sitio, que "& "sería reemplazado por" & a ".

  2. -------- Suponiendo que sepa cuántas columnas habrá en cada fila, puede usar la clase StringTokenizer (búsquelo, es increíble y está integrado en Java. Un buen lugar para buscar información es, como siempre, los Tutoriales de Java) para darle automáticamente los valores que necesita en forma de matriz.

    • Funciona al pasar una cadena y un delimitador (en este caso, el delimitador sería ','), y escupía todas las subcadenas que estaban separadas por esas comas. Si sabe cuántas piezas hay en total desde el primer momento, puede crear una instancia de una matriz 2D al principio y simplemente conectar cada fila que StringTokenizer les proporciona. Si no lo hace, todavía está bien, porque puede usar una ArrayList. Un ArrayList es bueno porque es una abstracción de nivel superior de una matriz que solicita automáticamente más memoria para que pueda continuar agregándole y saber que el tiempo de recuperación siempre será constante. Sin embargo, si planea agregar piezas dinámicamente y hacer eso con más frecuencia que recuperarlas, es posible que desee usar una LinkedList, porque tiene un tiempo de recuperación lineal, pero una relación mucho mejor que una ArrayList para agregar o quitar tiempo. O, si eres increíble, puedes usar una SkipList en su lugar. No sé si se implementan por defecto en Java, pero son increíbles. Advertencia justa, sin embargo; El costo de la velocidad en la recuperación, eliminación y colocación viene con una mayor sobrecarga en términos de memoria. Las listas de omisión mantienen muchos punteros.

    • Si sabe que debería haber el mismo número de valores en cada fila, y desea que estén organizados posicionalmente, pero por alguna razón su raspador no maneja la falta de un valor para una fila, y simplemente no lo pone valor, tiene algunas malas noticias ... sería más fácil reescribir la parte del código del raspador que trata con la falta de valores que escribir un método que interprete matrices de longitud variable e instancia un objeto Piece para cada formación. Mi sugerencia para esto sería nuevamente usar el carácter de control y llenar columnas vacías con & n (para 'nulo') para ser interpretado más tarde, pero luego los detalles son, por supuesto, lo que individualizará su código y estilo de codificación, así que no es para mí decirlo .

editar: Creo que lo principal en lo que debe centrarse es en aprender los diferentes tipos de datos de biblioteca estándar disponibles en Java, y tal vez aprender a implementar algunos de ellos usted mismo para practicar. Recuerdo haber implementado un árbol de búsqueda binario, no un árbol AVL, pero está bien. Es lo suficientemente divertido, es una buena práctica de codificación y, lo que es más importante, es necesario si quieres poder hacer las cosas de manera rápida y eficiente. No sé exactamente cómo Java implementa las matrices, porque la definición es "una sección contigua de memoria", sin embargo, puede asignarles memoria en Java en tiempo de ejecución utilizando variables ... pero independientemente de la implementación específica de Java, las matrices a menudo no son Es la mejor solución. Además, conocer expresiones regulares hace que todo sea mucho másmás fácil. Para practicar, recomendaría trabajarlos en sus programas Java o, si no quiere tener que compilar y mover cosas cada vez, sus scripts bash (si está usando * nix) y / o scripts por lotes (si estás usando Windows).

Respuesta: 2

Creo que la forma en que ha raspado los datos hace que este problema sea más difícil de lo necesario. Su raspado parece inconsistente y difícil de trabajar dado que la mayoría de los valores están rodeados de comillas de manera inconsistente, algunos datos ya tienen comas y no cada tarjeta está en su propia línea.

Intente volver a raspar los datos en un formato mucho más consistente, como:

R1C1|R1C2|R1C3|R1C4|R1C5|R1C6|R1C7|R1C8
R2C1|R2C2|R2C3|R2C4|R2C5|R2C6|R2C7|R3C8
R3C1|R3C2|R3C3|R3C4|R3C5|R3C6|R3C7|R3C8
R4C1|R4C2|R4C3|R4C4|R4C5|R4C6|R4C7|R4C8
A/D Changer|DREV-EN005|Effect Monster|Light|Warrior|100|100|You can remove from play this card in your Graveyard to select 1 monster on the field. Change its battle position.

Donde cada línea es definitivamente su propia tarjeta (a diferencia del ejemplo CSV que publicó con nuevas líneas en lugares impares) y el delimitador nunca se usa en un campo de datos como algo más que un delimitador.

Una vez que haya ingresado la entrada en un estado legible de manera consistente, se vuelve muy simple analizarla:

    BufferedReader br = new BufferedReader(new FileReader(new File("MonstersFinal.csv")));
    String line = "";

    ArrayList<String[]> cardList = new ArrayList<String[]>(); // Use an arraylist because we might not know how many cards we need to parse.

    while((line = br.readLine()) != null) { // Read a single line from the file until there are no more lines to read
        StringTokenizer st = new StringTokenizer(line, "|"); // "|" is the delimiter of our input file.
        String[] card = new String[8]; // Each card has 8 fields, so we need room for the 8 tokens.
        for(int i = 0; i < 8; i++) { // For each token in the line that we've read:
            String value = st.nextToken(); // Read the token
            card[i] = value; // Place the token into the ith "column"
        }
        cardList.add(card); // Add the card's info to the list of cards.
    }

    for(int i = 0; i < cardList.size(); i++) {
        for(int x = 0; x < cardList.get(i).length; x++) {
            System.out.printf("card[%d][%d]: ", i, x);
            System.out.println(cardList.get(i)[x]);
        }
    }

Lo que produciría el siguiente resultado para mi entrada de ejemplo dada:

card[0][0]: R1C1
card[0][1]: R1C2
card[0][2]: R1C3
card[0][3]: R1C4
card[0][4]: R1C5
card[0][5]: R1C6
card[0][6]: R1C7
card[0][7]: R1C8
card[1][0]: R2C1
card[1][1]: R2C2
card[1][2]: R2C3
card[1][3]: R2C4
card[1][4]: R2C5
card[1][5]: R2C6
card[1][6]: R2C7
card[1][7]: R3C8
card[2][0]: R3C1
card[2][1]: R3C2
card[2][2]: R3C3
card[2][3]: R3C4
card[2][4]: R3C5
card[2][5]: R3C6
card[2][6]: R3C7
card[2][7]: R4C8
card[3][0]: R4C1
card[3][1]: R4C2
card[3][2]: R4C3
card[3][3]: R4C4
card[3][4]: R4C5
card[3][5]: R4C6
card[3][6]: R4C7
card[3][7]: R4C8
card[4][0]: A/D Changer
card[4][1]: DREV-EN005
card[4][2]: Effect Monster
card[4][3]: Light
card[4][4]: Warrior
card[4][5]: 100
card[4][6]: 100
card[4][7]: You can remove from play this card in your Graveyard to select 1 monster on the field. Change its battle position.

Espero que volver a raspar la información sea una opción aquí y espero no haber entendido mal nada; ¡Buena suerte!

En una nota final, no olvides aprovechar OOP una vez que hayas solucionado las cosas. una Cardclase podría hacer que trabajar con los datos sea aún más simple.

Respuesta: 3

Uso Squirrel SQL como mi editor de Goto SQL para DB2 para iSeries, y una característica que me encanta es la autocorrección. Ingreso accesos directos en el editor como ssf y aparece "select * from". Sé que es posible ...

Estamos teniendo problemas para comprender la diferencia entre las reglas QUORUM y TWO ConsistencyLevel. Tenemos un clúster definido con 3 nodos, una NetworkTopologyStrategy y un SimpleSnitch. Si ...

Estoy tratando de crear una página web simple, en la que los animales tengan algunas propiedades (como nombre, animalType y balance) usando Thymeleaf. Sin embargo, he estado sufriendo la sintaxis adecuada. Mi código Java ...

¿Alguien puede ayudar? He leído varios blogs y parece incluir propiedades de i18n y otros archivos. Tengo que agregarlos como dependencia del módulo, elegir Jar .. Directorios y luego elegir "clases" ...