Подтвердить что ты не робот

Android, как сортировать JSONArray JSONObjects

Я сделал jsonarray jsonobjects. Теперь мне нужно отсортировать JSONArray на основе значения из jsonobjects. Раньше я сортировал ArrayLists пользовательских объектов вроде этого:

компараторы:

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

И затем сортируйте arraylist:

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

или

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

Но когда я пытаюсь сделать то же самое с JSONArray, как это (JA = my jsonarray)

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

the Collections.sort выдает сообщение об ошибке:

Сортировка метода (List, Comparator) в типе Collections не применима для аргументов (JSONArray, ThisActicity.KreeftenComparatorNL)

Кто-нибудь знает, как сортировать JSONArray?

4b9b3361

Ответ 1

Проблема в том, что JSONArray более или менее содержит JSONObjects (и другие JSONArrays), которые в конечном счете являются строками. Уничтожение строк полностью в POJO, сортировка их, а затем обратно в JSON довольно тяжелая.

Вторая проблема заключается в том, что JSONArray может содержать: Boolean, JSONArray, JSONObject, Number, String или объект JSONObject.NULL; то есть это смешанные типы, из-за чего трудно просто сбрасывать элементы в список какого-либо типа и сортировать, а затем передавать список, отсортированный по списку, обратно в массив JSON. единственный способ получить общий тип каждого элемента из JSONArray - это использовать метод Object get(). Конечно, тогда все объекты, которые у вас есть, являются объектами Object и не будут иметь возможности делать какую-либо значимую сортировку на них, не пересматривая проблема сериализации.

Предполагая, что ваш JSONArray содержит однородно структурированные значения, вы можете выполнять итерацию через JSONArray, вызывая один из типизированных методов get() на каждом из них, выгружая их в тип списка, а затем сортируя по этому вопросу. Если ваш JSONArray просто держит "простой" тип, например String или numbers, это относительно просто. Это не точный код, но что-то вроде:

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

Конечно, если у вас есть вложенные объекты, это может стать немного сложнее. Если значение (ы), которое вы хотите сортировать в режиме реального времени на верхнем уровне, возможно, это не так плохо...

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

Затем используйте такой компаратор, чтобы сортировать:

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

Опять же, это делает некоторые предположения относительно однородности данных в вашем JSONArray. При необходимости отрегулируйте свое дело. Также вам нужно будет добавить обработку исключений и т.д. Счастливое кодирование!

изменить исправлено на основе комментариев

Ответ 2

Просто, чтобы быть ясным, код выше для сортировщика сортировки неверен. Вы не можете сравнивать строку, как вы, как вы могли, на языке Ruby. Это можно было бы написать гораздо более лаконично следующим образом. В противном случае логика звучит.

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

Ответ 3

Чтобы заполнить список Android ArrayAdapter, мне нужно было сделать именно это. Вот как я это сделал:

Код операции, создающий список из 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);

И в JSONUtil (мой помощник):

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

Ответ 4

Один пример с полем 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);
 }

Ответ 5

Если вы собираетесь отображать данные, содержащиеся в JSONArray, тогда имеет смысл сортировать его в самом адаптере. Например, класс ArrayAdapter<T> уже имеет необходимые методы, такие как Insert, Remove и, конечно, Sort.

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

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

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

    }

});

Ответ 6

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

//Мой класс 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;
    }}