How to convert a 1D array with csv entries to a 2D array

Okay, so I am trying to figure out how to convert a 1D array, where each entry is a string of 8 comma delimited values, into a 2D array. There number of rows depends on what file the use is reading, so that is not a constant.

A small snippet of the 1D array:

205/55R16,24,5.5-7.5,6.5,8.4,7.6,24.9,837

205/45R17,23,6.5-7.5,7,8.1,7.4,24.3,859

205/50R17,25,5.5-7.5,6.5,8.4,7.5,25.1,830

215/45R17,24,7-8,7,8.4,7.7,24.7,845

The first entry in every row is a string, and the following 7 are values I want to use later as numbers. So how would I go about storing the first entry into a single column 1D array, and the last 7 entries into another 2D array?

To make it more complicated the third entry needs to be split into two different entries, making the 2D array an [m][8] array, m being the number of rows from the read file. The reason I won't be doing this by hand is I will in the end have a couple thousand lines to split, which is not an efficient process.

Thank you for the help!

Answers

  • Look at command split()

    There is a tutorial on 2D arrays

  • edited December 2016

    // forum.Processing.org/two/discussion/19888/
    // how-to-convert-a-1d-array-with-csv-entries-to-a-2d-array#Item_2
    
    // GoToLoop 2016-Dec-23
    
    CSVRow[] rows;
    
    void setup() {
      rows = createCSV(loadTable("values.csv"));
      printArray(rows);
      exit();
    }
    
    static final CSVRow[] createCSV(final Table t) {
      final CSVRow[] csv = new CSVRow[t.getRowCount()];
      int idx = 0;
    
      for (TableRow r : t.rows()) {
        final CSVRow entry = new CSVRow(r.getString(0));
    
        entry.ints[0] = r.getInt(1);
        entry.ints[1] = r.getInt(7);
    
        final float[] nums = float(split(r.getString(2), '-'));
        entry.floats[0] = nums[0];
        entry.floats[1] = nums[1];
    
        for (int i = 2; i < 6; entry.floats[i++] = r.getFloat(i));
    
        csv[idx++] = entry;
      }
    
      return csv;
    }
    
    static class CSVRow {
      final int[] ints = new int[2];
      final float[] floats = new float[6];
      final String s;
    
      CSVRow(String id) {
        s = id;
      }
    
      @ Override String toString() {
        final StringBuilder sb = new StringBuilder(s);
    
        sb.append(": ints: [");
        for (int i : ints)  sb.append(' ').append(i).append(',');
        sb.setLength(sb.length() - 1);
    
        sb.append(" ] floats: [");
        for (float f : floats)  sb.append(' ').append(f).append(',');
        sb.deleteCharAt(sb.length() - 1).append(" ]");
    
        return sb.toString();
      }
    }
    

    205/55R16,24,5.5-7.5,6.5,8.4,7.6,24.9,837
    205/45R17,23,6.5-7.5,7,8.1,7.4,24.3,859
    205/50R17,25,5.5-7.5,6.5,8.4,7.5,25.1,830
    215/45R17,24,7-8,7,8.4,7.7,24.7,845
    

  • GoToLoop, How would I modify this to work if I were to make the user select a file using the below code?

    void stockTireSelected(File selection)
    {
      if (selection == null)
      {
        println("Window was closed or the user hit cancel.");
      } else
      {
        println("User selected " + selection.getAbsolutePath());
        pathST = selection.getAbsolutePath();
    
        String STire[] = loadStrings(pathST);
      }
    }
    

    And when a button is pressed it will call this:

    public void Select_Stock_Tire(int theValue)
    {
      println("a button event from Select_Stock_Tire: " + theValue);
      selectInput("Select a file to process:", "stockTireSelected");
    }
    

    So once the user selects the file they desire, it will go in and using the path of the file, store the csv into a 1D array. I am doing this because I am structuring the data folder to separate different types of data. Meaning:

    - Data
              --> Cars
                      --> 2013 Ford Focus ST
                              --> Multiple .csv data files
                      --> 2017 Kia Forte5 EX
                              --> Multiple .csv data files
                      --> etc.
              --> Tire
                      --> Bridgestone Potenza S0-4 Pole Position.csv
                      --> Continental Extremecontact DW.csv
                      --> etc.
    

    I have the data for the cars part figured out as they are more seperated and done so on purpose. The tire data is obtained from a different source, and that data comes as a list of specs in a csv file, which is the snippet shown earlier, which isn't fun to analyze by hand. :-<

  • In String STire[] = loadStrings(pathST);, you're declaring a variable called STire locally.
    Therefore it only exists within the block it was declared. That's called variable scoping. :-B

  • I know it is probably wrong, but if I made it a global array, it would give me errors when I went to do STire[] = loadStrings(pathST); So I was really confused on what to do, I never went back and fixed it, which is a problem I know...but I am a mechanical engineering major, who likes to program, and the last time I did java was about 5 years ago. Since then I have lost a lot of what I used to know and am struggling on the simpler things, which sucks. :/

    I know there is a more efficient way to do this, but I am not sure of what to do.

    So, like I said, when a button "Select_Stock_Tire" is pressed it brings up a menu to go and select the file that has the correct brand and model in the title. This is done in the function:

    public void Select_Stock_Tire(int theValue)
    {
      println("a button event from Select_Stock_Tire: " + theValue);
      selectInput("Select a file to process:", "stockTireSelected");
    }
    

    This function calls the one I pasted below, I could just use that function to store the path, and make another function that processes the data from the csv and makes the 2D array. Do note that the code after the STire[] line was omitted as it was for debugging, but I wanted to convert it to a 2D array, so I looked online before finishing the code. I was planning on fixing it at some point after I figured that part out.

    void stockTireSelected(File selection)
    {
      if (selection == null)
      {
        println("Window was closed or the user hit cancel.");
      } else
      {
        println("User selected " + selection.getAbsolutePath());
        pathST = selection.getAbsolutePath();
    
        String STire[] = loadStrings(pathST);
      }
    }
    

    So when end up where we started. I am and ME who is confused and still lacks knowledge of java, and needs the help of someone on your level to make sense of things like how to implement your code. And I don't want to post the full code because it is a couple hundred lines long now...This project is porting a 5000+ line matlab project I made to java.

  • ... but if I made it a global array, it would give me errors when I went to do STire[] = loadStrings(pathST);

    selectInput() and its other "siblings" happen in a separate Thread.
    It means any code lines after it continue to get executed w/o waiting for it to get finished. @-)

    It's a good idea to declare some global variable to flag when selectInput() had successfully completed. *-:)

  • edited December 2016

    ... but I wanted to convert it to a 2D array, ...

    All elements from a Java array gotta be of the same (or compatible) datatype in which it was created.

    Your CSV are composed of 3 different datatypes: String, int & float.
    If you need them to be part of the same array, you'll have to store all of them as String. :-\"

  • Why do you need it as a 2D array? It seems to me that you could create a class (Tyre) to represent a tyre (1 row of data) and the individual data elements become attributes of the class. You would end up with a 1D array of Tyre objects.

    The first elemnt is the tyre size, what do the others mean?

  • // forum.Processing.org/two/discussion/19888/
    // how-to-convert-a-1d-array-with-csv-entries-to-a-2d-array#Item_2
    
    // GoToLoop 2016-Dec-25
    
    Tyre[] rows;
    
    void setup() {
      rows = createCSV(loadTable("values.csv"));
      printArray(rows);
      exit();
    }
    
    static final Tyre[] createCSV(final Table t) {
      final Tyre[] csv = new Tyre[t.getRowCount()];
      int idx = 0;
    
      for (TableRow r : t.rows()) {
        final Tyre entry = new Tyre(r.getString(0));
    
        entry.ints[0] = r.getInt(1);
        entry.ints[1] = r.getInt(7);
    
        final float[] nums = float(split(r.getString(2), '-'));
        entry.floats[0] = nums[0];
        entry.floats[1] = nums[1];
    
        for (int i = 2; i < 6; entry.floats[i++] = r.getFloat(i));
    
        csv[idx++] = entry;
      }
    
      return csv;
    }
    
    static class Tyre {
      final int[] ints = new int[2];
      final float[] floats = new float[6];
      final String model;
    
      Tyre(String s) {
        model = s;
      }
    
      @ Override String toString() {
        final StringBuilder sb = new StringBuilder(model);
        sb.append(": ints: ").append(java.util.Arrays.toString(ints));
        sb.append(" floats: ").append(java.util.Arrays.toString(floats));
        return sb.toString();
      }
    }
    
Sign In or Register to comment.