将具有重复键的JSON对象转换为JSON数组

时间:2014-06-25 19:27:53

标签: java json duplicates gson arrays

我有一个JSON字符串,我从包含重复键的数据库中获取。我想通过将它们的值组合到一个数组中来删除重复的键。

例如

输入

{
"a":"b",
"c":"d",
"c":"e",
"f":"g"
}

输出

{
"a":"b",
"c":["d","e"],
"f":"g"
}

实际数据是可以嵌套的大文件。我不会提前知道有什么对或有多对。

我需要使用Java。 org.json因重复键而抛出异常,gson可以解析字符串,但每个重复的键都会覆盖最后一个键。我需要保留所有数据。

如果可能,我想在不编辑任何库代码的情况下执行此操作

4 个答案:

答案 0 :(得分:2)

  

我想通过将它们的值组合到一个数组中来删除重复的键。

考虑JSON解析库以外的其他内容。这是一个非常简单的Java程序,使用String.split()方法将Json String转换为Map<String, List<String>> 而不使用任何库

示例代码:

String jsonString = ...
// remove enclosing braces and double quotes
jsonString = jsonString.substring(2, jsonString.length() - 2);

Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String values : jsonString.split("\",\"")) {
    String[] keyValue = values.split("\":\"");
    String key = keyValue[0];
    String value = keyValue[1];

    if (!map.containsKey(key)) {
        map.put(key, new ArrayList<String>());
    }
    map.get(key).add(value);
}

输出:

{
  "f": ["g"],
  "c": ["d","e"],
  "a": ["b"]
}

答案 1 :(得分:1)

截至今天,org.json库版本20170516提供accumulate()方法,将重复的关键字项存储到JSONArray

JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("a", "b");
jsonObject.accumulate("c", "d");
jsonObject.accumulate("c", "e");
jsonObject.accumulate("f", "g");
System.out.println(jsonObject);

输出:
{
“一”: “B”,
“C”:[ “d”, “E”],
“F”: “克”
}

答案 2 :(得分:0)

为了达到你想要的效果,你需要创建某种自定义类,因为JSON在技术上不能在一个键上有2个值。以下是一个例子:

public class SomeClass {

Map<String, List<Object>> values = new HashMap<String, List<Object>>();

public void add(String key, Object o) {
    List<Object> value = new ArrayList<Object>();
    if (values.containsKey(key)) {
        value = values.get(key);
    }
    value.add(o);
    values.put(key, value);
}

public JSONObject toJson() throws JSONException {
    JSONObject json = new JSONObject();
    JSONArray tempArray = null;

    for (Entry<String, List<Object>> en : values.entrySet()) {
        tempArray = new JSONArray();
        for (Object o : en.getValue()) {
            tempArray.add(o);
        }
        json.put(en.getKey(), tempArray);
    }

    return json;
}
}

然后,您可以从数据库中检索值,使用数据库中的列名称调用.add(String key, Object o)函数,以及值(作为Object参数)。完成后请致电.toJson()

答案 3 :(得分:0)

感谢Mike Elofson和Braj帮助我朝着正确的方向前进。我只想让具有多个值的键成为数组,所以我不得不稍微修改一下代码。最终我希望它也适用于嵌套的JSON,因为它目前假设它是平的。但是,以下代码适用于我目前所需的内容。

public static String repeatedKeysToArrays(String jsonIn) throws JSONException 
{
    //This assumes that the json is flat
    String jsonString = jsonIn.substring(2, jsonIn.length() - 2);

    JSONObject obj = new JSONObject();
    for (String values : jsonString.split("\",\"")) {
        String[] keyValue = values.split("\":\"");
        String key = keyValue[0];
        String value = ""; 
        if (keyValue.length>1) value = keyValue[1];

        if (!obj.has(key)) {
            obj.put(key, value);
        } else {
            Object Oold = obj.get(key);
            ArrayList<String> newlist = new ArrayList<String>();

            //Try to cast as JSONArray. Otherwise, assume it is a String
            if (Oold.getClass().equals(JSONArray.class)) {
                JSONArray old = (JSONArray)Oold;
                //Build replacement value
                for (int i=0; i<old.length(); i++) {
                    newlist.add( old.getString(i) );
                }
            }
            else if (Oold.getClass().equals(String.class)) newlist = new ArrayList<String>(Arrays.asList(new String[] {(String)Oold})); 
            newlist.add(value);

            JSONArray newarr = new JSONArray( newlist );
            obj.put(key,newarr);                
        }
    }
    return obj.toString();
}