我有一个函数,允许我使用另一个JSON对象作为过滤器过滤掉某些JSON文件。
参见代码:
public Map<String, Entry<JsonObject, Long>> loadFilter(Coll<?> coll, JsonObject filter){
// Create Ret
Map<String, Entry<JsonObject, Long>> ret = null;
// Get Directory
File directory = getDirectory(coll);
if ( ! directory.isDirectory()) return ret;
// Find All
File[] files = directory.listFiles(JsonFileFilter.get());
// Create Ret
ret = new LinkedHashMap<String, Entry<JsonObject, Long>>(files.length);
// Filter rules
Set<Map.Entry<String, JsonElement>> filterRules = filter.entrySet();
// For Each Found
for (File file : files)
{
// Get ID
String id = idFromFile(file);
// Get Entry
Entry<JsonObject, Long> entry = loadFile(file);
// Trying to fix a weird condition causing a NPE error
if(entry == null) continue;
if(entry.getKey() == null) continue;
// Compare the files with the given filter
Set<Map.Entry<String, JsonElement>> fileEntries = entry.getKey().entrySet();
if (fileEntries.containsAll(filterRules)) {
// Add found data to return list
ret.put(id, entry);
}
}
return ret;
}
想象一下,我有以下JSON:
{
"objects": [
"object1",
"object2"
],
}
我要做的是过滤掉数组对象包含object1的所有文件。我不关心对象2,我希望过滤出对象数组中至少包含object1的文件。
以下代码不会产生任何结果:
JsonObject filter = new JsonObject();
JsonArray array = new JsonArray();
array.add(new JsonPrimitive("object1"));
filter.add("objects", array);
Map<String, Entry<JsonObject, Long>> result = loadFilter(coll, filter); // nothing
任何帮助都是适当的。
答案 0 :(得分:2)
您的代码
if (fileEntries.containsAll(filterRules)) {
检查文件是否包含相等的元素,因此,在数组的情况下,它会检查数组是否相等,而不是包含另一个的元素。
没有本地方法可以在Gson中进行比较,因此必须在代码中完成。
我建议这样的解决方案:
private static boolean checkJsonPredicate(JsonElement element, JsonElement predicate) {
if (predicate == null) {
return true;
}
if (element == null || predicate.getClass() != element.getClass()) {
return false;
}
if (predicate.isJsonObject()) {
return predicate.getAsJsonObject().entrySet().stream()
.allMatch(e -> checkJsonPredicate(element.getAsJsonObject().get(e.getKey()), e.getValue()));
}
if (predicate.isJsonArray()) {
return StreamSupport.stream(predicate.getAsJsonArray().spliterator(), false)
.allMatch(element.getAsJsonArray()::contains);
}
return predicate.equals(element);
}
我使用Stream API来检查element
JSON中的数组是否包含predicate
JSON中的所有元素。
此代码处理嵌套对象(因此即使您的数组不在根级别,它仍然可以工作)。但是,如果数组本身包含对象,则对象必须相等。