loop jsonarray fromjson example java android json sorting

fromjson - iterate jsonarray java gson



Android cómo ordenar JSONArray de JSONObjects (6)

He hecho un jsonarray de jsonobjects. Ahora necesito ordenar el JSONArray en base a un valor de los jsonobjects. Anteriormente ordené ArrayLists de objetos personalizados como este:

Comparadores

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

Y luego ordenar el arraylist:

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

o:

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

Pero cuando intento lo mismo con el JSONArray como este (JA = my jsonarray)

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

el Collections.sort da un error:

El método de clasificación (Lista, Comparador) en el tipo Colecciones no es aplicable para los argumentos (JSONArray, ThisActicity.KreeftenComparatorNL)

¿Alguien sabe cómo ordenar el JSONArray?


El problema es que JSONArray contiene más o menos JSONObjects (y otros JSONArrays) que en última instancia son cadenas. Deserializar las cadenas por completo en POJOs, clasificarlas y luego volver a JSON es bastante pesado.

El segundo problema es que un JSONArray puede contener: Boolean, JSONArray, JSONObject, Number, String o el objeto JSONObject.NULL; es decir, se trata de tipos mixtos, lo que dificulta el simple hecho de volcar los elementos en una Lista de algún tipo y ordenar eso, luego pasar a través de la lista de elementos de volcado de nuevo a la matriz JSON. La única forma segura de obtener un tipo común de cada elemento de JSONArray es mediante el método Object get (). Por supuesto, todo lo que tiene son objetos Object y no podrá realizar ninguna clasificación significativa sin volver a visitar el Problema de serialización.

Suponiendo que su JSONArray contenga valores estructurados homogéneamente, podría iterar a través del JSONArray, llamando a uno de los métodos tipificados get () en cada uno, volcándolos en un tipo de Lista, y luego ordenándolos. Si su JSONArray solo contiene un tipo "simple" como Cadena o números, esto es relativamente fácil. Este no es un código exacto sino algo como:

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

Por supuesto, si tiene objetos anidados, esto puede ser un poco más complicado. Si los valores que desea ordenar viven en el nivel superior, puede que no sea tan malo ...

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

Luego usa un comparador como este para ordenar:

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

Nuevamente, esto hace algunas suposiciones sobre la homogeneidad de los datos en su JSONArray. Ajuste a su caso si es posible. También necesitarás agregar tu manejo de excepciones, etc. ¡Feliz codificación!

Edición fija basada en comentarios.


Para llenar una lista de Android, ArrayAdapter necesitaba hacer esto. Así es como lo hice:

Código de actividad que construye una lista desde 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);

Y en JSONUtil (mi ayudante):

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


Si va a mostrar los datos contenidos en el JSONArray entonces puede tener sentido clasificarlos en el propio adaptador. Por ejemplo, la ArrayAdapter<T> ya tiene los métodos necesarios, como Insert , Remove y, por supuesto, Sort .

adapter.sort(new Comparator<JSONObject>(){ @Override public int compare(JSONObject arg0, JSONObject arg1) { return arg0.optString("SortField", "").compareTo(arg1.optString("SortField","")) ; } });


Solo para dejar en claro el código anterior para el comparador de clasificación no es correcto. No puedes comparar una cadena como la que tienes arriba, como podrías hacerlo en un lenguaje como Ruby. Esto podría escribirse mucho más sucintamente como sigue. De lo contrario la lógica es sana.

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


Un ejemplo con campo de Date :

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


//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; }

// Mi clase Halper

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