2017-09-15 8 views
4

フィルタとして別のJSONオブジェクトを使用して特定の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" 
    ], 
} 

は、配列オブジェクトは、オブジェクト1含まれているすべてのファイルを除外しています。私はオブジェクト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 

すべてのヘルプがにappriciatedされます。

答えて

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); 
} 

を私はelement JSONの配列は、predicate JSONからすべての要素が含まれているかどうかを確認するために、ストリームAPIを使用していました。

このコードはネストされたオブジェクトを処理します(したがって、配列がルートレベルにない場合でも動作します)。しかし、配列自体にオブジェクトが含まれている場合、オブジェクトは等しくなければなりません。

+0

ご迷惑をおかけしました。私は基本的には、私はこの関数に、私のフルフィルターで持っているすべての配列を置くだろうか? –

+0

正しいですが、 'predicate'は配列である複数のフィールドを持つ' JsonObject'です。 – izstas

0

現在、キー値のペアが等しいかどうかを比較しているので、必要なのはobjectsキーの値を比較することです。

私がしようとしているのは、配列オブジェクト にobject1が含まれているファイルを除外することです。

objectsキーにアクセスし、値を比較してください。

Gson gson = new Gson(); 

// Filter object rule 
List<JsonElement> objectRules = gson.fromJson(filter.get("objects"), ArrayList.class); 
// Compare the files with the given object filter 
List<JsonElement> objectEntries = gson.fromJson(entry.getKey().get("objects"), ArrayList.class); 

if (objectEntries.containsAll(objectRules)) {...} 

何か

関連する問題