我有一个JSON字符串,我从包含重复键的数据库中获取。我想通过将它们的值组合到一个数组中来删除重复的键。
例如
输入
{
"a":"b",
"c":"d",
"c":"e",
"f":"g"
}
输出
{
"a":"b",
"c":["d","e"],
"f":"g"
}
实际数据是可以嵌套的大文件。我不会提前知道有什么对或有多对。
我需要使用Java。 org.json因重复键而抛出异常,gson可以解析字符串,但每个重复的键都会覆盖最后一个键。我需要保留所有数据。
如果可能,我想在不编辑任何库代码的情况下执行此操作
答案 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();
}