0

私の問題は、PHPは配列が連続していて、ゼロインデックスで始まるかどうかに基づいて、配列を異なる方法でエンコードすることです。例:

$arr = array(array(12), array(13));
===> [[12], [13]]

$arr = array("0" => array(12), "1" => array(13));
===> [[12], [13]]

$arr = array("0" => array(12), "2" => array(13));
===> {"0": [12], "2": [13]}

なぜ3番目のものはそれほど根本的に異なるのですか?

最初の例はリストのリストを生成し、3番目の例はリストを含むオブジェクトを生成します。これらすべてをJavaに変換する必要がありますMap<Integer, List<Double>>。これは、これらのPHPオブジェクトについてJavaで見つけることができる最も一般的なデータ型です。GoogleのGsonを使用しています。ただし、例ではさまざまなタイプのオブジェクトが生成されるため、これをマップに読み込むことはできません。最初にインデックスがあるかどうかを確認してから、カスタムマップに1つずつ追加する必要があります。「この部分を行うには、より良い方法である必要があります」という行を見てください。これは私のコードです:

import java.lang.StringBuilder;
import com.google.gson.*;
import com.google.gson.reflect.*;
import java.util.Map;
import java.util.HashMap;
import java.util.List;

public class Saving {

    public static void main(String[] args) {

        String json = "[[12], [13]]";
        json = json.trim();
        Map<Integer, List<Double>> fuelSavings = null;

        // such a cluster****
        if(json.startsWith("[[")) { // THERE HAS TO BE A BETTER WAY TO DO THIS PART
        // ANY WAY I CAN AVOID THIS ENTIRE IF CONDITION

            //implicit keys
            fuelSavings = new HashMap<Integer, List<Double>>();
            List<List<Double>> temporaryList = new Gson().fromJson(json, new TypeToken<List<List<Double>>>(){}.getType());
            int index = 0;
            for(List<Double> temporaryListMember: temporaryList) {
                fuelSavings.put(index, temporaryListMember);
                index++;
            }

        } else {

            // explicit keys
            // THIS PART IS PERFECT
            fuelSavings = new Gson().fromJson(json, new TypeToken<Map<Integer, List<Double>>>(){}.getType());

        }

        System.out.println(fuelSavings);

    }

}

どんな助けでもありがたいです、ありがとう!

4

2 に答える 2

0

PHPで行うことは、2つの異なることです。PHPの配列は、配列、マップ、リストとして機能します。

array(array(12), array(13));PHPでも同じではありarray("0" => array(12), "2" => array(13));ません。

Gsonを使用してJavaで行う必要があるのは、jsonをStringとして解析し、メインオブジェクトがaであるMapかaListであるかを確認してから、アドバイスすることです。あなたがリストをロードしたなら、あなたはそれがarray(array(12), array(13));そうでなければそれが他のものであったことを知っています。

PHP側から何かを実行して、常に同じように生成することはできませんか?

編集:

PHP側から何もできない場合、チェックはJsonParser解析をインスタンス化してからJsonObject.isJsonArray()trueが返されるかどうかをチェックするのと同じですが、最終的には高速になりますが、gsonライブラリに依存しません。

Map<Integer, List<Double>> fuelSavings = null;
JsonElement jElement = new JsonParser().parse("[[12], [13]]");
JsonObject jObject = jelement.getAsJsonObject();
if (jObject.isJsonArray()) {
    fuelSavings = new HashMap<Integer, List<Double>>();
    List<List<Double>> temporaryList = new Gson().fromJson(jElement, new TypeToken<List<List<Double>>>(){}.getType());
    int index = 0;
    for(List<Double> temporaryListMember: temporaryList) {
        fuelSavings.put(index++, temporaryListMember);
    }
} else /* this is a map */ {
    fuelSavings = new Gson().fromJson(jElement, new TypeToken<Map<Integer, List<Double>>>(){}.getType());
}
于 2012-09-11T19:12:51.550 に答える
0

とても興味深い!

私が理解したように、PHPサーバーはデータをJSONとしてエンコードされた順序付きマップとして提供しますが、運が悪い場合、そのキーは連続した整数であるjson_encode()ため、単純な配列として理解され、出力されるJSONに異なる形式が使用されます。

私が理解しているように、すべてのPHP配列は順序付けられたマップです。ただし、1つの配列に連続する整数キーがある場合json_encode()、「JSONオブジェクト」(マップ)の代わりにキーのない配列を生成します。そして、それは「オブジェクト」の代わりに配列を期待していないクライアントのコードを壊します。

JsonArray信じられないことに、をに変換する既存のJava関数が見つかりませんJsonObjectでした。配列をオブジェクトとして取得しようとすると、例外が発生することもあります。おやおや、aJsonArrayは暗黙の連続した整数キーを持つだけですJsonObject、それは自動的にキャストされるべきです!! :p

私はそれを試しませんでしたが、多分それJsonObject::entrySet()を解決することができます。IntegerがStringを自動的に解析し、適切な。で変換できる場合は、を返します。これは、 Set<Map.Entry<String,JsonElement>>に変換される可能性があります。Map<Integer, AnyObject>JsonElementTypeToken

于 2012-12-26T22:41:00.297 に答える