Jsonobjectのjsonarrayを作成しました。ここで、jsonobjectsの値に基づいてJSONArrayをソートする必要があります。以前は、次のようにカスタムオブジェクトの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());
collections.sortはエラーを出します:
タイプCollectionsのメソッドsort(List、Comparator)は、引数(JSONArray、ThisActicity.KreeftenComparatorNL)には適用されません。
JSONArrayのソート方法を知っている人はいますか?
問題は、JSONArrayが最終的に文字列であるJSONObjects(およびその他のJSONArrays)を多かれ少なかれ保持することです。文字列を完全にPOJOにデシリアライズし、それらを並べ替えてからJSONに戻すのはかなり重いです。
2番目の問題は、JSONArrayに次を含めることができることです:ブール、JSONArray、JSONObject、Number、String、またはJSONObject.NULLオブジェクト。つまり、混合型であるため、要素を何らかの型のリストにダンプしてソートするのが難しくなり、リストを通過してソートされたアイテムをJSON配列に戻します。 JSONArrayから各要素の一般的なタイプを取得する唯一の特定の方法は、Object get()メソッドを使用することです。もちろん、オブジェクトオブジェクトのみであり、再検討しないとそれらに対して意味のあるソートを実行できません。シリアル化の問題。
JSONArrayに均一に構造化された値が含まれていると仮定すると、JSONArrayを反復処理し、それぞれに対して型指定されたget()メソッドの1つを呼び出し、それらをList型にダンプしてからソートできます。 JSONArrayが文字列や数字のような「単純な」型を保持している場合、これは比較的簡単です。これは正確なコードではなく、次のようなものです。
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のデータの均一性についていくつかの仮定を行います。可能であれば、ケースに合わせて調整してください。また、例外処理などを追加する必要があります。ハッピーコーディング!
編集コメントに基づいて修正
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;
}
明確にするために、ソートコンパレータの上記のコードは正しくありません。 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);
}
});
Date
フィールドを使用した1つの例:
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);
}
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","")) ;
}
});
//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;
}
// My 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;
}}