Reputation: 489
I have an arraylist of records that is from an input csv file. Some records have full columns but some have null. For example:
abc, 1441652452, 8.64015, 52.75034
abc, 1442279677,,
abc, 1442280570, 10.44255,148.78166
anyways, there could be more than one line of in complete records consecutively. if you look at the records, at position [2] and [3] lat and longs are being stored accordingly. what i want to do is to calculate the distance between (in the case of my example above) the third record and the fist record. (I already have the formula to calculate the distance between latlngs. Currently, this is what my code consists of:
for (int i = 0; i < oneUserRecord.size(); i++) {
String currentRecord = oneUserRecord.get(i);
String[] current = currentRecord.split(",");
double currentLat = Double.parseDouble(current[3]);
double currentLng = Double.parseDouble(current[4]);
}
What I initially planned to do was to retrieve the next record, and extract the next record's lat and long, and then find out the distance between the next and the current records' lat and longs. However, because of the incomplete records I thus won't be able to extract positions [3] and [4] simply because they don't exist in those strings. So, my question simply put is, how do I check whether positions [3] and [4] of the next record is empty, if it is empty, how do i assign the next record to be the following row of record to have a value for lat and long?
I had a logic, (continuing from the code above),
String nextRecord = "";
if ((oneUserRecord.get(i++).split(",")[3]).isEmpty()
|| (oneUserRecord.get(i++).split(",")[4]).isEmpty()) {
nextRecord = oneUserRecord.get(i++);
}
else {
nextRecord = oneUserRecord.get(i + 1);
}
String[] next = nextRecord.split(",");
double nextLat = Double.parseDouble(next[3]);
double nextLng = Double.parseDouble(next[4]);
but it didn't work, still got an out of bounds error. Is the a way I can improve on this, or another method for me to get the result I want?
Upvotes: 0
Views: 602
Reputation: 1
String current = oneUserRecord.get(i); String[] currentRecord = current.split(",");
double currentLat = 0, currentLng = 0;
if (((currentRecord[3].length() > 0) || (currentRecord[4].length() > 0))) {
currentLat = Double.parseDouble(currentRecord[3]);
currentLng = Double.parseDouble(currentRecord[4]);
} else {
}
double nextLat = 0, nextLng = 0;
if ((i + 1) < oneUserRecord.size()) {
String next = oneUserRecord.get(i + 1);
String[] nextRecord = next.split(",");
if (((nextRecord[3].length() > 0) || (nextRecord[4].length() > 0))) {
nextLat = Double.parseDouble(nextRecord[3]);
nextLng = Double.parseDouble(nextRecord[4]);
} else {
}
}
Upvotes: 0
Reputation: 489
Okay I've got it,
String current = oneUserRecord.get(i);
String[] currentRecord = current.split(",");
double currentLat = 0, currentLng = 0;
if (((currentRecord[3].length() > 0) || (currentRecord[4].length() > 0))) {
currentLat = Double.parseDouble(currentRecord[3]);
currentLng = Double.parseDouble(currentRecord[4]);
} else {
}
double nextLat = 0, nextLng = 0;
if ((i + 1) < oneUserRecord.size()) {
String next = oneUserRecord.get(i + 1);
String[] nextRecord = next.split(",");
if (((nextRecord[3].length() > 0) || (nextRecord[4].length() > 0))) {
nextLat = Double.parseDouble(nextRecord[3]);
nextLng = Double.parseDouble(nextRecord[4]);
} else {
}
}
Instead of checking whether is string in the column is empty I checked it by length instead. Somehow this doesn't throw me an empty string error. For both the current and next record the default lat and long is set to zero, so for the incomplete records they will have a default distance of zero for me to calculate easily, no need to skip incomplete records.
Thank you for the rest of your answers as well! Hope my solution might come in handy for the people who needs the same logic for their codes.
Upvotes: 0
Reputation: 3140
I think, your problem is that if:
if ((oneUserRecord.get(i++).split(",")[3]).isEmpty()
|| (oneUserRecord.get(i++).split(",")[4]).isEmpty()) {
nextRecord = oneUserRecord.get(i++);
}
you are incrementing i
once, twice or three times. Don't use i++
in your condition. ++ is an operator that increment variable and returns value from before incrementation. Use i+1
in your condition, when you want to get next row without incrementing i
Upvotes: 1
Reputation: 415
You should avoid splitting any record more than once. Furthermore this can not work as intended due to the input.
Your example shows that some values might be completely missing. This is different from having empty values.
For example ",,," would mean empty values but "" means a single empty string. If you have such incomplete entries no one can say which would be the empty entries. For example should "a,b,d" translate into ["a", "b", "", "d"] or ["a", "b", "d", ""]? This can only be done by some logic / parser you have to implement.
In your case the following should be sufficient:
String nextRecord = oneUserRecord.get(i++).split(",", -1);
while (nextRecord.length < 4) {
nextRecord = oneUserRecord.get(i++).split(",", -1);
}
@Edit: The problem described above does not occur with valid input as changed in th question. However you should still use String#split(String, int) as shown. Otherwise you will get unexpected results in some cases, for example
"a,b,c,".split()
will only return an array with 3 elements.
Upvotes: 1