Comment trier les JSONArray de JSONObjects

j'ai fait un jsonarray de jsonobjects. Maintenant je dois trier le JSONArray sur la base d'une valeur des jsonobjects. Auparavant, j'ai trié des tableaux d'objets personnalisés comme ceci:

Comparateurs:

public class KreeftenComparatorLA implements Comparator<Kreeft> {
    public int compare(Kreeft left, Kreeft right) {
        return left.latijnseNaam.compareTo(right.latijnseNaam);
    }
}
public class KreeftenComparatorNL implements Comparator<Kreeft> {
    public int compare(Kreeft left, Kreeft right) {
        return left.naam.compareTo(right.naam);
    }
}

puis trier l'arraylist:

Collections.sort(db.lijst, new KreeftenComparatorLA());

ou:

Collections.sort(db.lijst, new KreeftenComparatorNL());

Mais lorsque je tente la même chose avec le JSONArray comme ceci (JA = mon jsonarray)

Collections.sort(JA, new KreeftenComparatorNL());

les Collections.trier donne une erreur:

la méthode sort (List, Comparator) dans les Collections de type n'est pas applicable pour les arguments (JSONArray, ThisActicity.KreeftenComparatorNL)--5-->

quelqu'un sait-il trier le JSONArray?

19
demandé sur Simon 2012-10-15 22:27:40

6 réponses

le problème est que JSONArray tient plus ou moins JSONObjects (et autres JSONArrays) qui sont finalement des chaînes. Désérialiser les cordes entièrement en POJOs, les trier, puis revenir en JSON est assez lourd.

le second problème est qu'un JSONArray peut contenir: booléen, JSONArray, JSONObject, Number, String, ou le JSONObject.Objet NULL; c'est-à-types différents, ce qui rend difficile la juste vider les éléments dans une Liste de certains types et de les trier, puis passer à travers la liste jeter les articles triés de nouveau dans le tableau de JSON. la seule façon certaine d'obtenir un type commun de chaque élément à partir du JSONArray est d'utiliser la méthode Object get ().. bien sûr, tout ce que vous avez, C'est des objets objet et vous ne pourrez pas les trier de manière significative sans revoir la question de la sérialisation.

en supposant que votre JSONArray contient des valeurs structurées de manière homogène, vous pouvez itérer à travers le JSONArray, en appelant une des méthodes typed get() sur chacune d'elles, en les rejetant dans un type de liste, puis le tri sur ça. Si votre JSONArray ne contient que le type" simple " comme une chaîne ou des nombres, c'est relativement facile. Ce n'est pas le code exact mais quelque chose comme:

List<String> jsonValues = new ArrayList<String>();
for (int i = 0; i < myJsonArray.length(); i++)
   jsonValues.add(myJsonArray.getString(i));
Collections.sort(jsonValues);
JSONArray sortedJsonArray = new JSONArray(jsonValues);

bien sûr, si vous avez des objets imbriqués cela peut devenir un peu plus délicat. Si la(Les) valeur (s) que vous voulez trier en direct dans le niveau supérieur, il ne peut pas être soo mauvais...

List<JSONObject> jsonValues = new ArrayList<JSONObject>();
for (int i = 0; i < myJsonArray.length(); i++)
   jsonValues.add(myJsonArray.getJSONObject(i));

Ensuite, utilisez un comparateur comme ceci:

class JSONComparator implements Comparator<JSONObject>
{

    public int compare(JSONObject a, JSONObject b)
    {
        //valA and valB could be any simple type, such as number, string, whatever
        String valA = a.get("keyOfValueToSortBy");
        String valB = b.get("keyOfValueToSortBy");

        return valA.compareTo(valB);
        //if your value is numeric:
        //if(valA > valB)
        //    return 1;
        //if(valA < valB)
        //    return -1;
        //return 0;    
    }
}

encore une fois, cela fait quelques hypothèses sur le homogénéité des données dans votre JSONArray. À adapter à votre cas si possible. Vous devrez également ajouter votre gestion des exceptions,etc. Amusez-vous bien!

modifier fixe basé sur les commentaires

37
répondu speakingcode 2015-05-07 17:27:53

afin de remplir une Liste Android ArrayAdapter j'ai eu besoin de faire juste ceci. Voilà comment j'ai fait:

Code D'activité construire une liste à partir D'un JSONArray:

JSONArray kids = node.getJSONArray("contents");
kids = JSONUtil.sort(kids, new Comparator(){
   public int compare(Object a, Object b){
      JSONObject    ja = (JSONObject)a;
      JSONObject    jb = (JSONObject)b;
      return ja.optString("name", "").toLowerCase().compareTo(jb.optString("name", "").toLowerCase();
   }
});
// in my case I wanted the original larger object contents sorted...
node.put("contents", kids);
public static JSONArray sort(JSONArray array, Comparator c){
    List    asList = new ArrayList(array.length());
    for (int i=0; i<array.length(); i++){
      asList.add(array.opt(i));
    }
    Collections.sort(asList, c);
    JSONArray  res = new JSONArray();
    for (Object o : asList){
      res.put(o);
    }
    return res;
}
9
répondu Tim Beres 2012-10-31 20:47:33

juste pour être clair le code ci-dessus pour le comparateur de tri n'est pas correct. Vous ne pouvez pas comparer la chaîne comme vous avez ci-dessus que vous pourriez dans une langue comme Ruby. Ceci pourrait être écrit beaucoup plus succinctement comme suit. La logique est bonne.

Collections.sort( jsonValues, new Comparator<JSONObject>() {
    @Override
    public int compare(JSONObject a, JSONObject b) {
        String valA = new String();
        String valB = new String();

        try {
            valA = (String) a.get("keyOfValueToSortBy");
            valB = (String) b.get("keyOfValueToSortBy");
        } 
        catch (JSONException e) {
            Log.e(LOG_TAG, "JSONException in combineJSONArrays sort section", e);
        }

        return valA.compareTo(valB);
    }
});
7
répondu Aaron Dancygier 2016-02-18 11:25:44

Un exemple Date champ:

public class JsonObjectComparator implements Comparator<JSONObject> {
private final String fieldName;
private Class<? extends Comparable> fieldType;

public JsonObjectComparator(String fieldName, Class<? extends Comparable> fieldType) {
    this.fieldName = fieldName;
    this.fieldType = fieldType;
}    

@Override
public int compare(JSONObject a, JSONObject b) {
    String valA, valB;
    Comparable newInstance_valA, newInstance_valB;
    int comp = 0;
    try {
        Constructor<? extends Comparable> constructor = fieldType.getConstructor(String.class);            
        valA = a.getString(fieldName);
        valB = b.getString(fieldName);
        if (fieldType.equals(Date.class)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            newInstance_valA = dateFormat.parse(valA);            
            newInstance_valB = dateFormat.parse(valB);
        } else {
            newInstance_valA = constructor.newInstance(valA);            
            newInstance_valB = constructor.newInstance(valB);
        }
        comp = newInstance_valA.compareTo(newInstance_valB);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }

    if(comp > 0)
        return 1;
    if(comp < 0)
        return -1;
    return 0;
  }

}

public static void main(String[] args) throws JSONException {        
    JSONObject o1 = new JSONObject();
    o1.put("key1", "26-06-2014");
    JSONObject o2 = new JSONObject();
    o2.put("key1", "30-11-2011");
    JSONObject o3 = new JSONObject();
    o3.put("key1", "15-07-2014");

    JsonObjectComparator comparator = new JsonObjectComparator("key1", Date.class);
    List<JSONObject> l = new ArrayList<>();
    l.add(o1);
    l.add(o2);
    l.add(o3);

    Collections.sort(l, comparator);
 }
1
répondu Alex 2014-06-26 13:16:51

Si vous allez pour afficher les données contenues dans le JSONArray alors il peut être logique de le trier dans l'adaptateur lui-même. Par exemple, le ArrayAdapter<T> la classe a déjà les méthodes requises telles que Insert,Remove, et bien sûr Sort.

adapter.sort(new Comparator<JSONObject>(){

    @Override
    public int compare(JSONObject arg0, JSONObject arg1) {

        return arg0.optString("SortField", "").compareTo(arg1.optString("SortField","")) ;

    }

});
1
répondu Hugh Jeffner 2015-08-25 20:54:33
//My script
 //HEADER add final variables
    private final int TYPE_STRING = 1;
    private final int TYPE_INT = 2;
    private final int TYPE_DUBLE = 3;


//METHOD GET SORT JSONARRAY
public JSONArray  getSortJSONArray()
{
 JSONArray  json = new JSONArray  ([{"carid":"957502","vin":"XXXXX","carbrand":"CADILLAC","carmodel":"CTS","carname":"CADILLAC CTS седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carmodificationname":" седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carcolorname":"Opulent Blue Metallic - ярко-синий металлик","price":"3410000","rgb":"","volumereal":"2,00","power":"276"},{"carid":"957502","vin":"XXXXX","carbrand":"CADILLAC","carmodel":"CTS","carname":"CADILLAC CTS седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carmodificationname":" седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carcolorname":"Opulent Blue Metallic - ярко-синий металлик","price":"3460000","rgb":"","volumereal":"1,00","power":"272"}]");

 /*halper - My halper */
   JSONArray sorJsonArray = halper.sort(json, getComparator("power",TYPE_INT));
   return sorJsonArray;
}

private Comparator getComparator(final String tagJSON,final int type)
    {
        Comparator c =  new Comparator()
        {
            public int compare(Object a, Object b)
            {


                try
                {
                    JSONObject    ja = (JSONObject)a;
                    JSONObject    jb = (JSONObject)b;

                    switch (type)
                    {
                        case TYPE_STRING:// String
                          return ja.optString(tagJSON, "")
                                                .toLowerCase()
                                                .compareTo(jb.optString(tagJSON, "").toLowerCase());
                        case TYPE_INT:// int
                            int valA =  ja.getInt(tagJSON);
                            int valB =  jb.getInt(tagJSON);
                            if(valA > valB)
                                return 1;
                            if(valA < valB)
                                return -1;

                        case TYPE_DUBLE:// double
                            String v1 = ja.getString(tagJSON).replace(",",".");
                            String v2 = jb.getString(tagJSON).replace(",",".");

                            double valAd = new Double(v1);// ja.getDouble(tagJSON);
                            double valBd = new Double(v2);//  jb.getDouble(tagJSON);
                            if(valAd > valBd)
                                return 1;
                            if(valAd < valBd)
                                return -1;

                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                return 0;
            }
        };

        return c;
    }

//Mon Halper classe

public class Halpe {
    public void Halpe(){}

    public static JSONArray sort(JSONArray array, Comparator c)
    {
        List    asList = new ArrayList(array.length());
        for (int i=0; i<array.length(); i++){
            asList.add(array.opt(i));
        }
        Collections.sort(asList, c);
        JSONArray  res = new JSONArray();
        for (Object o : asList){
            res.put(o);
        }
        return res;
    }}
0
répondu Aleksandr K 2016-06-02 14:05:26