# How to add values to array based on condition? (read two files)

**URL:** <https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340>\
**Category:** Coding Questions\
**Created:** [March 8, 2021, 2:36pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340 "2021-03-08T14:36:11Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 8, 2021, 2:36pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/1 "2021-03-08T14:36:11Z")

</div>

I have data from two csv files that I import as Tables. The first file contains country names and their population. The second file contains migration flows between countries over 4 time periods. The files would look like this in table form:

File 1:

```auto
+----------+------------+
| country | population |
+----------+------------+
| countryA | 100000 |
+----------+------------+
| countryB | 200000 |
+----------+------------+
| countryC | 300000 |
+----------+------------+
...

```

File 2:

```auto
+----------------+--------------+---------+---------+---------+---------+
| country_origin | country_dest | mig1990 | mig1995 | mig2000 | mig2005 |
+----------------+--------------+---------+---------+---------+---------+
| countryA | countryB | 100 | 100 | 100 | 100 |
+----------------+--------------+---------+---------+---------+---------+
| countryA | countryC | 200 | 200 | 200 | 200 |
+----------------+--------------+---------+---------+---------+---------+
| countryB | countryA | 300 | 300 | 300 | 300 |
+----------------+--------------+---------+---------+---------+---------+
| countryB | countryC | 400 | 400 | 400 | 400 |
+----------------+--------------+---------+---------+---------+---------+
...

```

I would like to visualize the countries as spheres (with size corresponding to population size) and connect them with lines (with line thickness corresponding to migration flow size). The spheres are located randomly in space. The spheres are colored with sequential colors using lerpColor() and initial values `start = color(204, 102, 0);` and `end = color(0, 102, 153);` The lines have a color gradient between the starting sphere and the end sphere.

I’ve created a class “Country”, which takes the following parameters:

```auto
  // Instance Variables
  int population;
  PVector coordinates;
  float posx, posy, posz;
  color sphereColor;
  int[] flowNumArray;
  String origin;
  String destination;
  int mig1990, mig1995, mig2000, mig2005;

  // Constructor Declaration of Class <-- this is a function, only call when we want a new item
  // To create a new instance
  Country(int population, float posx, float posy, float posz, color sphereColor, String origin, String destination, int mig1990, int mig1995, int mig2000, int mig2005) {
    this.population = population;
    this.coordinates = new PVector(posx, posy, posz);
    this.sphereColor = sphereColor;
    this.origin = origin;
    this.destination = destination;
    this.flowNumArray = new int[] {
    mig1990, mig1995, mig2000, mig2005
  };
  }
}

```

Now I’m struggling to add the values from both tables into my class so that each instance contains all the values that are associated with a country. The challenge is that the population table is much shorter than the migration table, so I can’t just loop over the values. When I call this in my for-loop for the population table:

`countries.add(new Country(countryName, posx, posy, posz, sphereColor));`

I get the error `The constructor "Country(String, float, float, float, int)" does not exist` (I understand why but how do I fix it?)

I suppose I need a (or two?) for loop that takes all the values from either table and adds them to a Country instance. Or I create the instance in one for-loop and then append it in a second for-loop based on the condition that the `country==country_origin`? I would appreciate if you could show me some skeleton code on how to do this. Thanks!

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 9, 2021, 6:45am UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/2 "2021-03-09T06:45:15Z")

</div>

No. Better Make a 2nd class Migration and arraylist of it. Each contains reference to two cities and year etc

---

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 9, 2021, 5:45pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/3 "2021-03-09T17:45:03Z")

</div>

Do you mean that every migration class would should it just contain one country pair and the size of the migration flow? Or should it be one origin country and all of its destination countries?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 9, 2021, 6:19pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/4 "2021-03-09T18:19:42Z")

</div>

> [@tea\_tree](#):
>
> Do you mean that every migration class would should it just contain one country pair and the size of the migration flow?

Yes, this is what I mean. Every object in the _Migration ArrayList_ has one country pair.  
The size of the migration flow must be an array over time within an object I guess.

But there are several ways of doing this.

**Remark**

By the way: when you need to check whether a country is already registered you can look at StringList - but I don’t think you need this

so the idea is:

- read File 1: store countries in ArrayList 1 (no duplicates in countries)
- read File 2: store migration data in ArrayList 2 - (no new countries compared to File 1)

Chrisir

---

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 9, 2021, 7:28pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/5 "2021-03-09T19:28:01Z")

</div>

I see how I’d do this to create spheres and lines. But how about creating a gradient in the line that changes color from the starting sphere to the end sphere? Wouldn’t I need to have all the sphere data in the same class as the migration flow data so I could do something like

```auto
for (int i = 0; i < class.size(); i++){
beginShape();
stroke(class.get(i).get.color()); //starting color of gradient
line(class.get(i).coordinates.get(posx), class.get(i).coordinates.get(posy), class.get(i).coordinates.get(posz));
stroke(class.get(i-1).get.color()); //end color of gradient
endShape;
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 9, 2021, 9:08pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/6 "2021-03-09T21:08:11Z")

</div>

> [@tea\_tree](#):
>
> But how about creating a gradient in the line that changes color from the starting sphere to the end sphere?

to be honest, apart from the data model you use, I wouldn’t know how to make a line with a color gradient in the first place. Even if I had just `line(100,200, 300, 500);`

> [@tea\_tree](#):
>
> Wouldn’t I need to have all the sphere data in the same class as the migration flow data

In my point of view: No.

Instead the migration object would have the indexes of the two cities and in the Migration class you  
would say:

```auto
void display() {
    City city1 = cities.get(indexFromCity); 
    City city2 = cities.get(indexToCity); 
    
    strokeWeight(map(migNumber, 0, 400000, 1, 9) ); 
    
    line(city1.posx, city1.posy, 
         city2.posx, city2.posy);  
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 11, 2021, 11:06am UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/7 "2021-03-11T11:06:39Z")

</div>

any progress here…?

just make a test Sketch

I can help you

---

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 11, 2021, 3:07pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/8 "2021-03-11T15:07:06Z")

</div>

Thank you so much. So, I did get it to work but I ended up pursuing my initial idea a bit further:

In my class, I created an ArrayList of destinations and an ArrayList of int-arrays.

```auto
  // Instance Variables
  int population;
  PVector coordinates;
  float posx, posy, posz;
  color sphereColor;
  ArrayList<ArrayList<Integer>> flowNumArray = new ArrayList<ArrayList<Integer>>();
  String origin;
  ArrayList<String> destination = new ArrayList<String>();
  int[] mig1990, mig1995, mig2000, mig2005;

  Country(int population, float posx, float posy, float posz, color sphereColor, String origin, String destination, int mig1990, int mig1995, int mig2000, int mig2005) {
    this.population = population;
    this.coordinates = new PVector(posx, posy, posz);
    this.sphereColor = sphereColor;
    this.origin = origin;
    this.destination = destination;
    this.flowNumArray = new int[] {
    mig1990, mig1995, mig2000, mig2005
  };
  }
}

```

Then when I instantiated the class, I simply called 2 nested for loops. One for origin etc. and another for-loop for the destinations and their associated values.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 11, 2021, 3:35pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/9 "2021-03-11T15:35:51Z")

</div>

here is my version with two classes

```auto
// https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340

ArrayList<City> cities = new ArrayList(); 
ArrayList<Migration> migrations = new ArrayList();

String[] countryData = 
  {
  "country,population", 
  "countryA,100000", 
  "countryB,200000", 
  "countryC,300000" 
};

String[] migData = 
  {
  "country_origin,country_dest,mig1990,mig1995,mig2000,mig2005", 
  "countryA,countryB,100,100,100,100", 
  "countryA,countryC,200,200,200,200", 
  "countryB,countryA,300,300,300,300", 
  "countryB,countryC,400,400,400,400"
};

void setup() {
  size(1660, 860);
  background(111); 

  // read data 
  for (String stringOneLineCity : countryData) {
    String[] sLineParts=split(stringOneLineCity, ",");

    if (!sLineParts[1].equals("population")) {
      City newCity = new City (sLineParts[0], sLineParts[1]);
      cities.add(newCity);
    }//if
  }//for

  // read data 
  for (String stringOneLineMigration : migData) {
    String[] sLineParts=split(stringOneLineMigration, ",");

    int from = getCity(sLineParts[0]);
    int to = getCity(sLineParts[1]); 
    if ( ! (from == -1 || to == -1) ) {
      Migration newMigration = new Migration (from, to, 
        sLineParts[2], sLineParts[3], 
        sLineParts[4], sLineParts[5] );
      migrations.add(newMigration);
    }//if
  }//for
}//func

void draw() {
  background(111); 
  // display 1
  for (City c : cities) {
    c.display();
  }

  // display 2
  for (Migration m : migrations) {
    m.display();
  }
}//func

int getCity(String c_) {
  // returns the index of a city in the ArrayList cities
  // based on the name of the city 
  int i=0; 
  for (City c : cities) {
    if (c.name.equals(c_))
      return i;
    i++;
  }
  println("getCity failed with " 
    +c_);
  return -1;
}

// ==================================================================================

class City {

  float posx=random(100, width-100), 
    posy=random(100, height-100);
  String name="";
  int pop=0; 
  color col=color(random(255), random(255), random(255) ); 

  //constr 
  City(String name_, String pop_) {
    name=name_;
    pop=int(pop_);
  }//constr 

  void display() {
    //
    strokeWeight(1); 
    fill(col); 
    ellipse(posx, posy, 
      pop/1000, pop/1000);
  }//
  //
}//class

// ==================================================================================

class Migration {

  int indexFromCity; 
  int indexToCity;

  String[] migData; 

  //constr 
  Migration(int from, int to, 
    String... vals) {
    //
    indexFromCity=from; 
    indexToCity=to;
    migData = vals;
  }//constr 

  void display() {
    City city1 = cities.get(indexFromCity); 
    City city2 = cities.get(indexToCity); 

    stroke(0); 

    strokeWeight(map(int(migData[0]), 
      0, 400, 1, 15) ); 

    line(city1.posx, city1.posy, 
      city2.posx, city2.posy);

    //reset 
    strokeWeight(1);
  }
  //
}//class
//

```

---

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 11, 2021, 6:36pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/10 "2021-03-11T18:36:50Z")

</div>

Very elegant, although I’m still working through it. I’m new to OOP and I have to wrap my head around how each class does more than just store data.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 11, 2021, 7:47pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/11 "2021-03-11T19:47:29Z")

</div>

I haven’t done the development of migration over time though

I didn’t have time to read your post, I was very busy

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 13, 2021, 7:07am UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/12 "2021-03-13T07:07:11Z")

</div>

I don’t know how to draw a line with gradient

Maybe shader, see tutorial

Of course you can make a line pf pixels yourself

Look at for-loop, lerp() and lerpColor

---

<div class="post-metadata">

**Author:** ![tea\_tree](https://avatars.discourse-cdn.com/v4/letter/t/d6d6ee/32.png) [@tea\_tree](https://discourse.processing.org/u/tea_tree)\
**Post date:** [March 13, 2021, 4:35pm UTC](https://discourse.processing.org/t/how-to-add-values-to-array-based-on-condition-read-two-files/28340/13 "2021-03-13T16:35:41Z")

</div>

I’ve managed to draw a line with a gradient. Essentially, you create a beginshape, endshape environment. Inside, you first set the color for one side, specify two vertices. Then you set the color for the other side and draw two vertices like so

```auto
beginShape();
stroke(0,0,0);
vertex(0,0,0);
vertex(5,5,5);
stroke(255,255,255);
vertex(10,10,10);
vertex(15,15,15);
endShape();

```
