How can I sort JSON by ID?

Hello all,

I am working on a complex JSON file.
I load the entire file (list of items A and each item has different JSON-Arrays and JSON-Objects in it).
I don’t copy it into an Array of a class but just work with the loaded entire JSON file. Is that ok/recommended?

When displaying the file, I like to sort the items A by their ID (number like 2022234). How is that possible?

Thank you!

Chrisir

(coming from here: Can I make a small windows app for taking time and log production times?)

I suggest you look into comparators. If you can make a comparator that takes in your objects or arrays and reduces it to a value then it would be fairly simple to sort numerically using Collections.sort().

Not entirely sure how your data is coming in and haven’t used these in a while so I don’t think this is right but should give you a basic idea of what I’m thinking. Might have to add some imports in processing for collections or comparator.

Collections.sort(/* your JSONArray */, new Comparator<JSONArray>() {
  public int compare(JSONArray json1, JSONArray json2) {
    return json1.id - json2.id;
  }
});
1 Like

Thanks, but I am not sure, this applies.

As I tried to say, I don’t use a class but keep all data in the JSON Object.

Can you give a sample of an equivalent structured JSON, showing at least two IDs?

I agree that Comparator is probably the way to go. Depending on your data structure, something like:

  1. create a Comparator that checks two JSONObjects and returns the difference of their id fields.
  2. load your JSONArray of JSONObjects into an ArrayList myList
  3. call Collections.sort(myList, idComparator).
  4. Loop over the sorted JSONObjects and write them into a single JSONArray.
1 Like

AD 1

Up to now I just work with the JSON object. I don’t have a class / objects/ Arraylist of it.

Not sure what you mean?

Can I say

Arraylist <JSONOBJECT> arrlist1 = new Arraylist ();

Do you mean this?

AD 3

Do I rebuild the entire list from scratch?

See also

That doesn’t work at all

Can you please post a simple example?

Are you trying to sort the JSON objects in your other linked post by their number keys?

Solved

(I sorted a more simple ArrayList toolTimers first instead of sorting the JSON. )


import java.util.Collections; 
import java.util.Comparator;  

...


// vars for measuring Time (Space Bar and e)
ArrayList<ToolTimer> toolTimers = new ArrayList<ToolTimer>(); 

.....
  // this sorts 
  Collections.sort(toolTimers, new TimerComparator());

....




class TimerComparator implements Comparator<ToolTimer> {
  @Override
    public int compare (ToolTimer a, ToolTimer b) {

    if (a.timeArticleIndex.equals("") )
      println("equals ++++++++++++++++++++++++");

    //if a<b return -1;
    //if a==b return 0;
    //else return 1; 
    //return a.timeArticleIndex < b.timeArticleIndex ? -1 : 
    //  a.timeArticleIndex == b.timeArticleIndex ? 0 :
    //  1;

    return a.timeArticleIndex.compareToIgnoreCase( b.timeArticleIndex);
  }
}//class
1 Like

thanks for coming back

Solved

(I sorted a more simple ArrayList toolTimers first instead of sorting the JSON. )

thank you very much!

1 Like

Sorry I just want to apply this sort to my JSONArray

The JSONArray consists of JSONObjects. Each of those has an id, by which I want to sort.

that’s what I try

class JSONComparator implements Comparator<JSONArray> {
  @Override
    public int compare (JSONArray a, JSONArray b) {

    //if (a.timeArticleIndex.equals("") )
    //  println("equals ++++++++++++++++++++++++");

    //if a<b return -1;
    //if a==b return 0;
    //else return 1; 
    //return a.timeArticleIndex < b.timeArticleIndex ? -1 : 
    //  a.timeArticleIndex == b.timeArticleIndex ? 0 :
    //  1;

    return a.getJSONObject().getString("id").compareToIgnoreCase( b.getJSONObject().getString("id") );
  }
}//class

Is it possible?

The Error message

It says

The function “getJSONObject()” expects parameters like: “getJSONObject(int)”

for this line:


    return a.getJSONObject().getString("id").compareToIgnoreCase( b.getJSONObject().getString("id") );

but which parameter do I havee to put there: a.getJSONObject()

thank you!

Chrisir

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:

  1. copy the objects from the JSONArray to a List,
  2. sort the List object, passing .sort() your Comparator for JSONObjects so it will sort in that way
  3. copy the objects from the now-sorted List into a new JSONArray.
1 Like

Hm.

But when I have a Arraylist of
Jsonobject, I still have to use a.getString(„id“) in the comparator class?

Will this work?

And do I have to make a copy function
to fill the jsonobject for bringing it in the arraylist?

Keep in mind what a Comparator does.

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

  1. a JSONArray of JSONObjects, json
  2. 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
1 Like

This works.

Thank you so much!

Question

ok, I have a few article IDs that are very long.

like 8329141234

I’d like to treat them as long instead of int

But how can I achieve this?

I’d like to use long() (like int()) on a String, but long() doesn’t exist

(also I don’t know how to say 123L (using “L”) as suggested here: https://processing.org/reference/long.html)

It is supposed to work in the context below

Thank you again!

Great Work!

Chrisir

class JSONComparator implements Comparator<JSONObject> {
  @Override
    public int compare (JSONObject a, JSONObject b) {

    //if a<b return -1;
    //if a==b return 0;
    //else return 1; 
    int aIndex= int(   a.getString("id").replace("-", ""));   /// !!!!!!
    int bIndex= int(   b.getString("id").replace("-", "")); /// !!!!!!
    return aIndex < bIndex ? -1 :        /// !!!!!!
      aIndex == bIndex ? 0 :
      1;
  }
}//class
1 Like

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")));
    }
}

Edit: fixed up Long.compare line

1 Like

That’s working.

Besides very long article IDs like here I also have another kind of IDs that contain letters like
hlm123. Long crashes here but int doesn’t

In theory I could treat the 2 cases of IDs separately within the same comparator class, right?

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?

sort as strings, alpha

abc123
hlm123
hml3

vs alpha / num

abc123
hml3
hlm123

1 Like

Ok, so it would be cool to have a sort method with JSONArray