【问题标题】:How to filter nested JSON values?如何过滤嵌套的 JSON 值?
【发布时间】:2021-03-09 08:19:42
【问题描述】:

我有一个如下所示的 JSON 文件。我想读取所有值并检查输入字符串是否包含 JSON 值之一,返回 true。但在我的尝试下,它总是返回false

{
  "RECORDS": [
    {
      "word": "word1",
      "language": "en"
    },
    {
      "word": "word2",
      "language": "en"
    },
    {
      "word": "word3",
      "language": "en"
    }
  ]
}

我的方法


 public static boolean check(String content) throws IOException {
        File file = ResourceUtils.getFile("classpath:sample.json");

        ObjectMapper mapper = new ObjectMapper();
        Map<?, ?> map = mapper.readValue(file, Map.class);
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            if (content.contains(entry.getValue().toString())) {
                return true;
            } else
                return false;
        }

        return false;
    }

【问题讨论】:

  • return true 中断循环迭代,并从函数中返回您始终在最底部 return false
  • 似乎问题在于.contains() 比较。你想要什么样的结果?如果要检查json中是否存在content,条件应该是:entry.getValue().toString().contains(content)
  • @Dharma entry.getValue().toString().contains(content) 仅在内容完全等于 json 值时才有效。如果内容是一个段落,则再次返回 false。
  • @SeniorFullstack 你能建议我如何解决这个问题吗?

标签: java collections java-8 jackson java-stream


【解决方案1】:

试试这个:

return mapper.readValue(file, new TypeReference<Map<String, List<Map<String, String>>>>() {})
             .values()
             .stream()
             .flatMap(List::stream)
             .map(Map::values)
             .flatMap(Collection::stream)
             .anyMatch(content::contains);

上面的代码 sn-p 将检查您的content 字符串是否包含任何嵌套值(例如word1enword2 ...)


如果您只查找 word 字段的值,请尝试以下操作:

return mapper.readValue("", new TypeReference<Map<String, List<Map<String, String>>>>() {})
             .values()
             .stream()
             .flatMap(List::stream)
             .map(m -> m.get("word"))
             .anyMatch(content::contains);

【讨论】:

  • 谢谢,但它给了我一个错误Map&lt;String, Map&lt;String, String&gt;&gt;(){}),它说'&gt;' or ',' expected
  • 两种方式都会抛出异常Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.LinkedHashMap&lt;java.lang.Object,java.lang.Object&gt; out of START_ARRAY token
  • @FaramarzAfzali 对,我错过了嵌套的List&lt;&gt;。更新了答案。
【解决方案2】:

for (Map.Entry&lt;?, ?&gt; entry : map.entrySet()) 会给你一个 LinkedHashMap 条目。所以基本上,你的入口变量看起来像这样:

为了让您的代码正常工作,您需要在执行contains 检查之前再次迭代这些值

【讨论】:

  • 谢谢,@Hasham Rasheed,现在我有了像 [{word=word1, language=en}, {word=word2, language=en}, {word=word3, language=en}, 这样的 JSON 对象我如何提取 word 值来检查输入是否包含它??
猜你喜欢
  • 1970-01-01
  • 2018-05-25
  • 2015-02-17
  • 2014-08-19
  • 2020-08-16
  • 2022-01-17
  • 2019-02-19
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多