the type of the expression must be an array type but resolved to int

edited December 2017 in Questions about Code

I'm trying to basically get this double loop in order to access the values of the data structure below: p1[0], p1[1], p1[2], p2[0], p2[1], etc. Not really sure why this isn't working

for (int i = 1; i < 3; i++) {
      for (int j = 0; j < 3; j++){
      println("p"+i[j]);
      }
    }

    //dummy stanza one
    String[] p1 = {
      "this is the first", 
      "this is the second", 
      "this it the third"
    };
    //dummy stanza two
    String[] p2 = {
      "1", 
      "2", 
      "3"
    };
    //dummy stanza three
    String[] p3 = {
      "one", 
      "two", 
      "three"
    };

Answers

  • You can't create variables from strings like that. You could use a HashMap instead. More info can be found in the reference.

  • How would you use this to solve the problem? I'm not sure I understand? I need to programmatically reference this data structure in a for loop...

  • If you have a lot of characters, you store them in a string.

    If you have a lot of strings, you store them in an array of strings.

    If you have a lot of arrays of strings, you... store them in different arrays of strings? NO!

    If you have a lot of arrays of strings, you store them in an ARRAY of arrays of strings.

    String [][] p = {
      {
        "this is the first", 
        "this is the second", 
        "this it the third"
      }, {
        "1", 
        "2", 
        "3"
      }, {
        "one", 
        "two", 
        "three"
      }
    };
    
    for ( int i = 0; i < 3; i++ ) {
      for ( int j = 0; j < 3; j++ ) {
        println( p[i][j] );
      }
    }
    
  • edited December 2017

    The problem @Tfguy44 is that the data is mixed type.

    I have 1.) a string and 2.) two floats, a lat and a lon

    but I don't think processing allows you to do mixed type arrays...

    Shame on me for not including my actual data structure; here it is:

    //dummy stanza one
    String[] p1 = {
      "this is the first", 
      "this is the second", 
      "this it the third"
    };
    float[] p1lat = {
      -122.434216, 
      -122.480198, 
      -122.418789
    };
    float[] p1lon = {
      37.734181, 
      37.750747, 
      37.738618
    };
    //dummy stanza two
    String[] p2 = {
      "1", 
      "2", 
      "3"
    };
    float[] p2lat = {
      -122.444216, 
      -122.490198, 
      -122.428789
    };
    float[] p2lon = {
      37.734181, 
      37.750747, 
      37.738618
    };
    //dummy stanza three
    String[] p3 = {
      "one", 
      "two", 
      "three"
    };
    float[] p3lat = {
      -122.424216, 
      -122.470198, 
      -122.408789
    };
    float[] p3lon = {
      37.734181, 
      37.750747, 
      37.738618
    };
    

    So, what I'm really trying to pull is:

    p1 string 1, p1lat 1, p1lon 1
    p1 string 2, p1lat 2, p1lon 2
    p1 string 3, p1lat 3, p1lon 3
    p2 string 1, p2lat 1, p2lon 1
    

    and so forth and so on, but with a for loop

  • You need a class to put all that data into, keep it all together in an object rather than combining it by type in disjointed arrays. There's a FAQ over in Common Questions that has examples.

  • edited December 2017

    @koogs; I'm not exactly sure that's the strategy I want to take, but could you link to that FAQ? Right now, I have a "reader class" that pulls in this array data does a pretty complex/cool visualization (embedding these strings in a 3D map). I basically just want to have an easy way to write down:

    string/lat/lon string/lat/lon etc.

    and then this other class will hoover it up and make the data visualization.

  • edited December 2017

    https://Processing.org/reference/HashMap.html
    https://Docs.Oracle.com/javase/8/docs/api/java/awt/geom/Point2D.Float.html

    /**
     * Array of HashMapped Stanzas (v1.0)
     * GoToLoop (2017/Dec/11)
     *
     * Forum.Processing.org/two/discussion/25460/
     * the-type-of-the-expression-must-be-an-array-type-but-resolved-to-int#Item_8
     */
    
    import java.util.Map;
    import java.awt.geom.Point2D;
    
    static final int STANZAS = 3, COORDS = 3;
    static final float FACTOR = 1.01;
    final Map<String, Point2D.Float>[] stanzas = new Map[STANZAS];
    
    { // dummy stanza one:
      stanzas[0] = new HashMap<String, Point2D.Float>(COORDS, FACTOR);
      stanzas[0].put("this is the first", new Point2D.Float(-122.434216, 37.734181));
      stanzas[0].put("this is the second", new Point2D.Float(-122.480198, 37.750747));
      stanzas[0].put("this is the third", new Point2D.Float(-122.418789, 37.738618));
    }
    
    { // dummy stanza two:
      stanzas[1] = new HashMap<String, Point2D.Float>(COORDS, FACTOR);
      stanzas[1].put("1", new Point2D.Float(-122.444216, 37.734181));
      stanzas[1].put("2", new Point2D.Float(-122.490198, 37.750747));
      stanzas[1].put("3", new Point2D.Float(-122.428789, 37.738618));
    }
    
    { // dummy stanza three:
      stanzas[2] = new HashMap<String, Point2D.Float>(COORDS, FACTOR);
      stanzas[2].put("one", new Point2D.Float(-122.424216, 37.734181));
      stanzas[2].put("two", new Point2D.Float(-122.470198, 37.750747));
      stanzas[2].put("three", new Point2D.Float(-122.408789, 37.738618));
    }
    
    void setup() {
      printArray(stanzas);
      println();
    
      println(stanzas[0].get("this is the third")); // Float[-122.41879, 37.738617]
      println(stanzas[1].get("1").x);   // -122.444214
      println(stanzas[2].get("two").y); // 37.750748
    
      exit();
    }
    
  • edited December 2017 Answer ✓

    Another flavor! This time switching to a class w/ 1 String + 1 Point2D.Float fields.
    All contained by a 2D array: :-bd

    /**
     * Labeled Coords 2DArray (v1.0)
     * GoToLoop (2017/Dec/11)
     *
     * Forum.Processing.org/two/discussion/25460/
     * the-type-of-the-expression-must-be-an-array-type-but-resolved-to-int#Item_9
     */
    
    import java.awt.geom.Point2D;
    
    static final int STANZAS = 3, COORDS = 3;
    final LabelCoord[][] stanzas = new LabelCoord[STANZAS][COORDS];
    
    { // dummy stanza one:
      stanzas[0][0] = new LabelCoord("this is the first", -122.434216, 37.734181);
      stanzas[0][1] = new LabelCoord("this is the second", -122.480198, 37.750747);
      stanzas[0][2] = new LabelCoord("this is the third", -122.418789, 37.738618);
    }
    
    { // dummy stanza two:
      stanzas[1][0] = new LabelCoord("1", -122.444216, 37.734181);
      stanzas[1][1] = new LabelCoord("2", -122.490198, 37.750747);
      stanzas[1][2] = new LabelCoord("3", -122.428789, 37.738618);
    }
    
    { // dummy stanza three:
      stanzas[2][0] = new LabelCoord("one", -122.424216, 37.734181);
      stanzas[2][1] = new LabelCoord("two", -122.470198, 37.750747);
      stanzas[2][2] = new LabelCoord("three", -122.408789, 37.738618);
    }
    
    static final class LabelCoord {
      final String label;
      final Point2D.Float coord;
    
      LabelCoord(final String txt, final float lat, final float lon) {
        label = txt;
        coord = new Point2D.Float(lat, lon);
      }
    
      @ Override String toString() {
        return label + ": " + coord;
      }
    }
    
    void setup() {
      for (final LabelCoord[] lc : stanzas)  printArray(lc);
      println();
    
      println(stanzas[0][2].coord);   // Point2D.Float[-122.41879, 37.738617]
      println(stanzas[1][0].coord.x); // -122.444214
      println(stanzas[2][1].coord.y); // 37.750748
    
      exit();
    }
    
  • edited December 2017

    "Labeled Coords 2DArray (v2.0)" is almost the same as previous (v1.0).

    But LabelCoord rather than having 1 Point2D.Float field called coord, it instead extends Point2D.Float.

    This way, class LabelCoord has direct access to Point2D.Float's fields x & y and its methods. \m/

    /**
     * Labeled Coords 2DArray (v2.0)
     * GoToLoop (2017/Dec/11)
     *
     * Forum.Processing.org/two/discussion/25460/
     * the-type-of-the-expression-must-be-an-array-type-but-resolved-to-int#Item_10
     */
    
    import java.awt.geom.Point2D;
    
    static final int STANZAS = 3, COORDS = 3;
    final LabelCoord[][] stanzas = new LabelCoord[STANZAS][COORDS];
    
    { // dummy stanza one:
      stanzas[0][0] = new LabelCoord("this is the first", -122.434216, 37.734181);
      stanzas[0][1] = new LabelCoord("this is the second", -122.480198, 37.750747);
      stanzas[0][2] = new LabelCoord("this is the third", -122.418789, 37.738618);
    }
    
    { // dummy stanza two:
      stanzas[1][0] = new LabelCoord("1", -122.444216, 37.734181);
      stanzas[1][1] = new LabelCoord("2", -122.490198, 37.750747);
      stanzas[1][2] = new LabelCoord("3", -122.428789, 37.738618);
    }
    
    { // dummy stanza three:
      stanzas[2][0] = new LabelCoord("one", -122.424216, 37.734181);
      stanzas[2][1] = new LabelCoord("two", -122.470198, 37.750747);
      stanzas[2][2] = new LabelCoord("three", -122.408789, 37.738618);
    }
    
    static final class LabelCoord extends Point2D.Float {
      final String label;
    
      LabelCoord(final String txt, final float lat, final float lon) {
        super(lat, lon);
        label = txt;
      }
    
      @ Override String toString() {
        return label + ": " + super.toString();
      }
    }
    
    void setup() {
      for (final Point2D[] points : stanzas)  printArray(points);
      println();
    
      println(stanzas[0][2]);   // Point2D.Float[-122.41879, 37.738617]
      println(stanzas[1][0].x); // -122.444214
      println(stanzas[2][1].y); // 37.750748
    
      exit();
    }
    
  • @GoToLoop; I'm very intrigued by the data structure above; I'm going to try it, I very much think it is going to work. Thank you so much!

  • @GoToLoop also, question can I have stanzas with a different amount of entries? e.g. stanza 0 has 3 entries, stanza 1 has 2 entries?

  • It's your code. You can do whatever you want.

    But it sounds like you're looking for the append() function or the ArrayList class. The reference is your best friend.

  • @KevinWorkman; thank you for responding; I'm just looking to take the above example and be able to have dummy stanzas defined with a different amount of entries. I want to define it all in advance. I added another LabelCoord Object to "dummy stanza three", but I'm not sure how to loop through the double-for loop below without getting snagged on a null.

    import java.awt.geom.Point2D;
    
    static final int STANZAS = 3, COORDS = 4;
    final LabelCoord[][] stanzas = new LabelCoord[STANZAS][COORDS];
    
    { // dummy stanza one:
      stanzas[0][0] = new LabelCoord("this is the first", -122.434216, 37.734181);
      stanzas[0][1] = new LabelCoord("this is the second", -122.480198, 37.750747);
      stanzas[0][2] = new LabelCoord("this is the third", -122.418789, 37.738618);
    }
    
    { // dummy stanza two:
      stanzas[1][0] = new LabelCoord("1", -122.444216, 37.734181);
      stanzas[1][1] = new LabelCoord("2", -122.490198, 37.750747);
      stanzas[1][2] = new LabelCoord("3", -122.428789, 37.738618);
    }
    
    { // dummy stanza three:
      stanzas[2][0] = new LabelCoord("one", -122.424216, 37.734181);
      stanzas[2][1] = new LabelCoord("two", -122.470198, 37.750747);
      stanzas[2][2] = new LabelCoord("three", -122.408789, 37.738618);
      //this is my odd entry
      stanzas[2][3] = new LabelCoord("last", -122.408789, 37.738618);
    }
    
    static final class LabelCoord {
      final String label;
      final Point2D.Float coord;
    
      LabelCoord(final String txt, final float lat, final float lon) {
        label = txt;
        coord = new Point2D.Float(lat, lon);
      }
    
      @ Override String toString() {
        return label + ": " + coord;
      }
    }
    
    void setup() {
      for (int i = 0; i < stanzas.length; i++) {
        for (int j = 0; j < stanzas[i].length; j++) {
          println(stanzas[i][j].label);
          println(stanzas[i][j].coord.x); // -122.444214
          println(stanzas[i][j].coord.y); // 37.750748
        }
      }
      exit();
    }
    
  • @KevinWorkman; are you suggesting that I change this array into an arraylist in order to be able to achieve that?

  • edited December 2017 Answer ✓

    Sure! An array's last dimension can be created empty [] w/o specifying its length: :-bd

    • So rather than: final LabelCoord[][] stanzas = new LabelCoord[STANZAS][COORDS];
    • You can go w/: final LabelCoord[][] stanzas = new LabelCoord[STANZAS][];

    However, now we're gonna have to create the last dimension as many times as the 1st dimension's length. #:-S

    For "Labeled Coords 2DArray (v2.0)", let's say "dummy stanza two:" got now only 2 entries instead.

    Previous version w/ always length = 3 for new LabelCoord[STANZAS][COORDS];:

    { // dummy stanza two:
      stanzas[1][0] = new LabelCoord("1", -122.444216, 37.734181);
      stanzas[1][1] = new LabelCoord("2", -122.490198, 37.750747);
      stanzas[1][2] = new LabelCoord("3", -122.428789, 37.738618);
    }
    

    Now w/ just length = 2 for new LabelCoord[STANZAS][];:

    { // dummy stanza two:
      stanzas[1] = new LabelCoord[] {
        new LabelCoord("1", -122.444216, 37.734181), 
        new LabelCoord("2", -122.490198, 37.750747)
      };
    }
    
  • edited December 2017 Answer ✓

    Alternatively, you can instantiate the inner dimension w/ the desired length alone; and then assign its entries separately: ;)

    { // dummy stanza two:
      final LabelCoord[] coord = stanzas[1] = new LabelCoord[2];
      coord[0] = new LabelCoord("1", -122.444216, 37.734181); 
      coord[1] = new LabelCoord("2", -122.490198, 37.750747);
    }
    
  • @GoToLoop ; 1.) ultra insane thanks, 2.) check out what the code actually does: https://www.instagram.com/p/BGnt9WFiuEB/?taken-by=saito_koriel (3D map of city embedded text, virtual cameras head from point to point; creates a visualization based on this data we're talking about here), 3.) OK, got it, don't specify the length of the array in advance, but then why do you need this line:

    static final int STANZAS = 3, COORDS = 3;
    

    and why doesn't that declaration mess up the code? Everything seems to be working and doing exactly what I need it to do. Pasting it below just so that you can see that it checks out:

    import java.awt.geom.Point2D;

    static final int STANZAS = 3, COORDS = 3;
    final LabelCoord[][] stanzas = new LabelCoord[STANZAS][];
    
    { // dummy stanza one:
      stanzas[0] = new LabelCoord[] {
      new LabelCoord("this is the first", -122.434216, 37.734181),
      new LabelCoord("this is the second", -122.480198, 37.750747),
      new LabelCoord("this is the third", -122.418789, 37.738618)
      };
    }
    
    { // dummy stanza two:
      stanzas[1] = new LabelCoord[] {
        new LabelCoord("1", -122.444216, 37.734181), 
        new LabelCoord("2", -122.490198, 37.750747)
      };
    }
    
    { // dummy stanza three:
      stanzas[2] = new LabelCoord[] {
      new LabelCoord("one", -122.424216, 37.734181),
      new LabelCoord("two", -122.470198, 37.750747),
      new LabelCoord("three", -122.408789, 37.738618),
      new LabelCoord("last",-122.408789, 37.738618)
    };
    }
    
    static final class LabelCoord {
      final String label;
      final Point2D.Float coord;
    
      LabelCoord(final String txt, final float lat, final float lon) {
        label = txt;
        coord = new Point2D.Float(lat, lon);
      }
    
      @ Override String toString() {
        return label + ": " + coord;
      }
    }
    
    void setup() {
      for (int i = 0; i < stanzas.length; i++) {
        for (int j = 0; j < stanzas[i].length; j++) {
          println(stanzas[i][j].label);
          println(stanzas[i][j].coord.x); // -122.444214
          println(stanzas[i][j].coord.y); // 37.750748
        }
      }
      exit();
    }
    
  • edited December 2017

    And why doesn't that declaration mess up the code?

    Well, it's not messing up b/c COORDS isn't being used now. Just the constant STANZAS. :P

    You can simply erase constant COORDS outta the code since it isn't needed anymore. :-h

    It's merely a formality to state clearly an array's dimension for the next guy studying the code. ;))

  • edited December 2017

    In order to iterate over the 2D array, you can use 2 "enhanced" for ( : ) loops in place of "regular" for ( ; ; ) 1s: *-:)
    https://Processing.org/reference/for.html

    void setup() {
      for (Point2D[] points : stanzas)  for (Point2D coord : points)  println(coord);
      exit();
    }
    

    And given the last dimension is an array, we can go w/ just 1 for ( : ) loop + printArray(): :ar!
    https://Processing.org/reference/printArray_.html

    void setup() {
      for (Point2D[] points : stanzas)  printArray(points);
      exit();
    }
    
  • edited December 2017

    Oops! Just realized you're basing your code on v1.0 rather than v2.0! b-(

    B/c under v1.0, class LabelCoord doesn't extends Point2D.Float, we can't use the latter as the datatype for the former! :-@

    For those enhanced loops, just replace the more generic Point2D w/ the more specific LabelCoord datatype: :)>-


    void setup() {
      for (LabelCoord[] points: stanzas) for (LabelCoord coord: points) println(coord);
      exit();
    }
    

    void setup() {
      for (LabelCoord[] points : stanzas)  printArray(points);
      exit();
    }
    

    Notice though this solution now also works under v2.0, given the class is both datatype LabelCoord & Point2D.Float. :\">

Sign In or Register to comment.