2012-10-15 12 views
18

Zrobiłem jsonarray z jsonobjects. Teraz muszę posortować JSONArray na podstawie wartości z jsonobjects. Dawniej I klasyfikowane ArrayLists niestandardowych obiektów tak:Android, jak sortować JSONArray z JSONObjects

komparatory:

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

A potem posortować ArrayList:

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

czyli

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

Ale gdy próbuję to samo z JSONArray w ten sposób (JA = mój jsonarray)

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

Collections.sort daje błąd:

The method sort(List, Comparator) in the type Collections is not applicable for the arguments (JSONArray, ThisActicity.KreeftenComparatorNL)

Czy ktoś wie jak rozwiązać ten JSONArray?

+0

możliwe dupe od http://stackoverflow.com/questions/4833084/is-there-any-easy-way-to-sort- a-jsonarray-of-objects-by-an-atrybut-in-android? rq = 1 – petey

+0

Rozważ to: Jeśli możesz posortować przed zbudowaniem JsonArray, zrób to. Możesz również posortować go w JavaScript później. Myślę, że budowanie listy z JsonArray, sortowanie listy, a następnie przebudowanie JsonArray jest dość straszne :) –

Odpowiedz

34

Problem polega na tym, że JSONArray zawiera mniej lub więcej JSONObjectów (i innych JSONArrays), które ostatecznie są ciągami. Deserializacja łańcuchów w całości do POJO, ich sortowanie, a następnie powrót do JSON jest dość ciężki.

Drugim problemem jest to, że JSONArray może zawierać: Boolean, JSONArray, JSONObject, Number, String lub JSONObject.NULL; tj. jest to typ mieszany, co sprawia, że ​​trudno jest po prostu zrzucić elementy do listy pewnego rodzaju i posortować, a następnie przejść przez listę, przesyłając posortowane elementy z powrotem do tablicy JSON. jedynym sposobem na uzyskanie wspólnego typu każdego elementu z JSONArray jest użycie metody Object get(). Oczywiście wszystko, co masz, to obiekty Object i nie będzie w stanie przeprowadzić żadnego znaczącego sortowania bez ponownego przeglądania problem serializacji.

Zakładając, że JSONArray zawiera jednorodnie ustrukturyzowane wartości, możesz wykonać iterację za pomocą JSONArray, wywołując jedną z wpisanych metod get() na każdej z nich, umieszczając je na liście, a następnie sortując. Jeśli twój JSONArray ma po prostu "prosty" typ, jak ciąg lub liczby, jest to stosunkowo łatwe. To nie jest dokładny kod, ale coś takiego:

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

oczywiście, jeśli masz zagnieżdżone obiekty mogą to trochę trudniejsze. Jeśli wartość (y) chcesz posortować na żywo na najwyższym poziomie, to nie może być soo bad ...

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

Następnie użyj komparator tak uporządkować:

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

Ponownie , to czyni pewne założenia dotyczące jednorodności danych w twoim JSONArray. Dostosuj do swojego przypadku, jeśli to możliwe. Również musisz dodać obsługę wyjątków, itp. Szczęśliwe kodowanie!

edit ustalone na podstawie ich uwag

+0

update line Collections.sort (jsonValues); –

+2

Ten przykład jest blisko, ale nie kompiluje się. Nie można porównywać Strings w ten sposób, ponieważ Java nie ma przeciążenia operatora. Przykład powinien zwrócić valA.compareTo (valB). – SoWeLie

8

Wystarczy być jasne powyższy kod na komparator sortowania nie jest poprawna. Nie można porównywać ciągów, tak jak powyżej, w języku takim jak Ruby. Można to zapisać bardziej zwięźle w następujący sposób. W przeciwnym razie logika jest dobra.

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

Nie możesz po prostu zwrócić valA.compareTo (valB)? – SoWeLie

+1

Tak, masz rację, jeśli ... powrót nie jest konieczny. –

8

Aby wypełnić listę Androida, ArrayAdapter musiałem to zrobić. To jak to zrobiłem:

kod aktywny budowania listy z 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); 

I JSONUtil (mój pomocnika):

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

Może to zrobić w samym adapterze: http://stackoverflow.com/a/32213875/383761 –

1

Jeden przykład z Date polu:

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

Jeśli zamierzasz wyświetlić dane zawarte w JSONArray, to może mieć sens sortowanie go w samym adapterze. Na przykład klasa ArrayAdapter<T> ma już wymagane metody, takie jak Insert, Remove i oczywiście Sort.

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

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

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

    } 

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

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