Comparator sorts units. If you have a JSONArray of JSONObjects, you need to sort those objects in pairwise comparisons. This requires a List data structure that contains them. So:
copy the objects from the JSONArray to a List,
sort the List object, passing .sort() your Comparator for JSONObjects so it will sort in that way
copy the objects from the now-sorted List into a new JSONArray.
List<Foo> myfoos;
Comparator<Foo> fooComp;
myfoos.sort(fooComp); // now your list of Foos is sorted
sort() on a list of Foos takes a Comparator that works on pairs of individual Foos, Foo a, Foo b – the sort method uses the Comparator throughout the list until all the Foos are sorted. So your comparator should be for JSONObject a, JSONObject b, like this (untested):
class JSONObjectIDComparator implements Comparator<JSONObject> {
@Override
public int compare (JSONObject a, JSONObject b) {
return a.getInt("id") - b.getInt("id");
}
}
So. Given
a JSONArray of JSONObjects, json
a class JObjComparator implements Comparator // NOT JSONArray
and then given that you have loaded your objects into a List (ArrayList, etc):
JSONArray --> List myobjs;
then (pseudocode)
// sort your list
myobjs.sort(new JSONObjectIDComparator());
// create an array to put the sorted list in
jsonSorted = new JSONArray();
// append the objects in order
for(JSONObject obj : myobjs){
jsonA.append(obj)
}
// now your sorted list of objects are loaded in a JSONArray
float() is just a helper function in Processing – which is standardized on float, so it doesn’t have it long().
Use Long.valueOf() for your strings, and Long.compare() to compare two longs. (untested)
class JSONComparator implements Comparator<JSONObject> {
@Override
public int compare (JSONObject a, JSONObject b) {
return Long.compare(Long.valueOf(a.getString("id")), Long.valueOf(b.getString("id")));
}
}
So how do you want these sorted? As Strings? Or are there specific rules to the prefixes, like that they are always 3 letters long, and do you want to sort the prefixes alphabetically and the suffixes numerically?
There are lots of ways of doing this in Java. The best solutions depend on the specific use case. Do you need to support negative numbers? Can they be a decimal, and is it localized (. vs , etc)? Will there be scientific notation?
Or if you don’t want a wrapper function, you can extend JSONArray yourself. Here is an example based on the JSONArray reference example, but using a simple JSONObject id String comparator as in our discussion.
/**
* JSONArraySorting
* 2019-12 Extend JSONArray and add a custom sort
*/
// begin with the reference JSONArray example:
// https://processing.org/reference/JSONArray.html
import java.util.Collections; // added
import java.util.Comparator; // added
String[] species = { "Capra hircus", "Panthera pardus", "Equus zebra" };
String[] names = { "Goat", "Leopard", "Zebra" };
JSONArraySortable values; // change to extended class
void setup() {
values = new JSONArraySortable(); // change to extended class
for (int i = 0; i < species.length; i++) {
JSONObject animal = new JSONObject();
animal.setString("id", ""+(species.length-i)); // number w/Strings, 3-2-1
animal.setString("species", species[i]);
animal.setString("name", names[i]);
values.setJSONObject(i, animal);
}
saveJSONArray(values, "data/new.json"); // saves 3-2-1
// now sort the array by its object "id" keys and save it again
values.sort();
saveJSONArray(values, "data/new2.json"); // saves 1-2-3
}
class JSONArraySortable extends JSONArray {
// pairwise comparison logic for sort is in the Comparator
class JSONComparator implements Comparator<JSONObject> {
@Override
public int compare (JSONObject a, JSONObject b) {
return Long.compare(Long.valueOf(a.getString("id")), Long.valueOf(b.getString("id")));
}
}
// utility -- sort will need to get all objects from private ArrayList
ArrayList<JSONObject> getAll() {
ArrayList<JSONObject> myobjs = new ArrayList<JSONObject>();
for (int i=0; i<this.size(); i++) {
myobjs.add((JSONObject)this.get(i));
}
return myobjs;
}
// utility -- sort will need to clear all objects from private ArrayList
public void clear() {
for (int i=this.size()-1; i>=0; i--) {
this.remove(i);
}
}
// sort by getting all objects, sorting with comparator, clearing, and appending
public void sort() {
ArrayList<JSONObject> myobjs = this.getAll();
Collections.sort(myobjs, new JSONComparator());
this.clear();
for (int i=0; i<myobjs.size(); i++) {
this.append(myobjs.get(i));
}
}
}