gpt4 book ai didi

java - 检查 JSONObject 是否匹配 JSON boolean 表达式

转载 作者:行者123 更新时间:2023-12-04 03:31:12 26 4
gpt4 key购买 nike

为了正确解释这个问题,我必须从一个例子开始,假设我有一个这样的用户列表

[
{ "name": "John", "surname": "Doe", "age": 22 },
{ "name": "Syrus", "surname": "Black", "age": 20 }
]
我还有一个 JSONObject表示必须像这样匹配的条件:
{
"OR":[
{ "name": { "eq": "John"} },
{ "AND":[
{ "name": { "eq": "Syrus"} },
{ "age": { "gt": 18 } }
] }
]
}
应该翻译成:
name = "John" OR (name = "Syrus" AND age > 18)
现在我必须制作给出 JSONObject 的代码条件和用户列表检查每个用户是否符合条件。
目前这就是我所做的:
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.BiConsumer;
import com.query.Queryable;
import org.json.JSONArray;
import org.json.JSONObject;

public class QueryableTreeMap<K,V extends JSONObject> extends TreeMap<K,V> implements Queryable<JSONObject,JSONObject> {

private static final long serialVersionUID = 2586026774025401270L;

private static boolean test(Set<Map.Entry<String, Object>> condition, JSONObject value){
boolean isValid = true;
Iterator<Map.Entry<String, Object>> iter = condition.iterator();
while(iter.hasNext()){
Map.Entry<String, Object> subcond = iter.next();
if(subcond.getKey().equals("OR")){
//isValid = isValid || test((Set<Map.Entry<String, Object>>) subcond.getValue(), value);
} else if(subcond.getKey().equals("AND")){
//isValid = isValid && test((Set<Map.Entry<String, Object>>) subcond.getValue(), value);
} else if(subcond.getKey().equals("NOT")){

} else {

}
}
return isValid;
}

@Override
public JSONObject query(JSONObject query) {
// the set containing the conditions
Set<Map.Entry<String, Object>> entries = query.toMap().entrySet();
// the JSONArray with containing the records that match the condition
JSONArray array = new JSONArray();
// for each JSONObject inside this structure
this.forEach(new BiConsumer<K,JSONObject>(){

@Override
public void accept(K key, JSONObject value) {
// testing if the current record matches the condition
if(test(entries, value)) array.put(value);
}

});
// returns a JSONObject containing a JSONArray that contains the records that match the condition
return new JSONObject(array);
}
}
我目前被困在测试方法中,该方法应该实际上测试给定的对象是否与给定的条件匹配。
我不介意更改 JSON 条件的格式,只要它是 JSONObject .
目前,我提出了一个部分解决方案,该解决方案构建了一个名为 Condition 的对象,该对象表示 JSONObject 中的 boolean 表达式(效率不高,但仍然是一个可能的解决方案)这显然目前不起作用,我需要帮助解决我的问题现在应该做
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Condition {

private Condition left, right;
private String boolExpr, key, value;
private boolean not;
private int operationType; // greater then, less then, equal to, greater or equal of, less or equal of

public Condition(Map<String, Object> map) {
Set<Map.Entry<String, Object>> set = map.entrySet();
Iterator<Map.Entry<String, Object>> iterator = set.iterator();
while(iterator.hasNext()){
Object entry = iterator.next();
System.out.println(entry);
System.out.println(entry.getClass());
if(entry instanceof Map.Entry) {
String key = (String) ((Map.Entry) entry).getKey();
switch(key){
case "AND":
case "OR":
this.boolExpr = key;
break;
case "eq":
case "gt":
case "lt":
case "gte":
case "lte":
this.operationType = getOperationTypeFromString(key);
break;
case "NOT":
this.not = true;
break;
default:
this.key = key;
break;
}
}
}
}

public int getOperationTypeFromString(String operation) {
switch(operation){
case "eq":
return 0;
case "gt":
return 1;
case "lt":
return 2;
case "gte":
return 3;
case "lte":
return 4;
default:
return 0;
}
}

}
我宁愿不使用 Condition 类,而只使用 JSONObject。
我正在使用 org.json JSON-Java解析器。

最佳答案

编辑:代码更新为使用 org.json。
下面是处理您的示例的工作实现。
实际完成工作的函数是 match ,它递归地遍历过滤器并将每个节点应用于提供的对象。如果给定的对象满足给定的过滤器,则该函数返回 true。
从概念上讲 match函数将过滤器语言中的每个构造( ANDOREQLT 等)映射到它的 Java 等价物。例如。 AND映射到 Stream.allMatch , NOT映射到 Java !运算符(operator),EQ映射到 Object.equals等,即match正在定义过滤器语言的语义。
我希望代码是不言自明的 - 如果有任何不清楚的地方,请告诉我。

import org.json.*;

import java.io.*;
import java.nio.file.*;
import java.util.List;
import java.util.stream.*;

import static java.util.stream.Collectors.toList;

public class Test {

public static void main(String[] args) throws IOException {
final List<JSONObject> jsObjs =
stream(readJsonArray("users.json"))
.map(JSONObject.class::cast)
.collect(toList());

final JSONObject jsFilter = readJsonObject("filter.json");

final List<JSONObject> matches = applyFilter(jsObjs, jsFilter);

System.out.println(matches);
}

private static List<JSONObject> applyFilter(List<JSONObject> jsObjs, JSONObject jsFilter) {
return jsObjs.stream()
.filter(jsObj -> match(jsObj, jsFilter))
.collect(toList());
}

private static boolean match(JSONObject jsObj, JSONObject jsFilter) {

final String name = getSingleKey(jsFilter);
final Object value = jsFilter.get(name);

switch (name) {
case "AND":
return stream((JSONArray)value)
.map(JSONObject.class::cast)
.allMatch(jse -> match(jsObj, jse));
case "OR":
return stream((JSONArray)value)
.map(JSONObject.class::cast)
.anyMatch(jse -> match(jsObj, jse));
case "NOT":
return !match(jsObj, (JSONObject)((JSONArray)value).get(0));
default:
final JSONObject jsOp = (JSONObject)value;
final String operator = getSingleKey(jsOp);
final Object operand = jsOp.get(operator);
switch (operator) {
case "eq": return jsObj.get(name).equals(operand);
case "lt": return (Integer)jsObj.get(name) < (Integer)operand;
case "gt": return (Integer)jsObj.get(name) > (Integer)operand;
default: throw new IllegalArgumentException("Unexpected operator: " + operator);
}
}
}

private static JSONObject readJsonObject(String fileName) throws IOException {
try (Reader reader = Files.newBufferedReader(Paths.get(fileName))) {
return new JSONObject(new JSONTokener(reader));
}
}

private static JSONArray readJsonArray(String fileName) throws IOException {
try (Reader reader = Files.newBufferedReader(Paths.get(fileName))) {
return new JSONArray(new JSONTokener(reader));
}
}

private static Stream<Object> stream(JSONArray jsa) {
return StreamSupport.stream(jsa.spliterator(), false);
}

private static String getSingleKey(JSONObject jso) {
if (jso.length() != 1) {
throw new IllegalArgumentException("Expected single entry");
} else {
return jso.keySet().iterator().next();
}
}
}

关于java - 检查 JSONObject 是否匹配 JSON boolean 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66781122/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com