如何使用Argonaut解码键名有意义的非结构化JSON及动态键场景?
这个问题我碰到过好多次了!当API返回的JSON键是动态生成的时候,确实没法用固定的键名去取值,核心思路就是遍历键值对,而不是硬编码键。我给你举几个常用语言的例子,一看就懂:
先看个典型的API返回示例
假设加密货币API返回的JSON结构是这样的,键是动态的基础币种和计价币种:
{ "BTC": { "USD": 30000, "EUR": 27000 }, "ETH": { "USD": 1800, "EUR": 1600 } }
1. Python 处理方式
Python里可以直接用字典的items()方法遍历所有动态键值对:
# 模拟API返回的JSON数据 response_json = { "BTC": {"USD": 30000, "EUR": 27000}, "ETH": {"USD": 1800, "EUR": 1600} } # 遍历所有基础币种及其对应的计价数据 for base_currency, quote_data in response_json.items(): print(f"基础币种: {base_currency}") # 再遍历该基础币种下的所有计价币种和价格 for quote_currency, price in quote_data.items(): print(f" 对{quote_currency}的价格: {price}")
如果只关心特定计价币种(比如USD),可以加个筛选:
target_quote = "USD" for base, quotes in response_json.items(): if target_quote in quotes: print(f"{base}/{target_quote}: {quotes[target_quote]}")
2. JavaScript 处理方式
JS里用Object.entries()把对象转成键值对数组,再遍历:
// 模拟API返回的JSON数据 const responseJson = { "BTC": {"USD": 30000, "EUR": 27000}, "ETH": {"USD": 1800, "EUR": 1600} }; // 遍历所有基础币种 for (const [baseCurrency, quoteData] of Object.entries(responseJson)) { console.log(`基础币种: ${baseCurrency}`); // 遍历计价币种和价格 for (const [quoteCurrency, price] of Object.entries(quoteData)) { console.log(` 对${quoteCurrency}的价格: ${price}`); } }
同样,筛选特定计价币种的写法:
const targetQuote = "USD"; Object.entries(responseJson).forEach(([base, quotes]) => { if (quotes[targetQuote]) { console.log(`${base}/${targetQuote}: ${quotes[targetQuote]}`); } });
3. 强类型语言(比如Java)的处理方式
强类型语言里可以用Map来接收动态键的JSON,比如用Jackson库反序列化:
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; public class CryptoPriceParser { public static void main(String[] args) throws Exception { // 模拟API返回的JSON字符串 String json = "{\"BTC\":{\"USD\":30000,\"EUR\":27000},\"ETH\":{\"USD\":1800,\"EUR\":1600}}"; ObjectMapper mapper = new ObjectMapper(); // 反序列化为嵌套Map,对应动态键结构 Map<String, Map<String, Double>> priceData = mapper.readValue(json, Map.class); // 遍历所有键值对 for (Map.Entry<String, Map<String, Double>> baseEntry : priceData.entrySet()) { String baseCurrency = baseEntry.getKey(); System.out.println("基础币种: " + baseCurrency); Map<String, Double> quotes = baseEntry.getValue(); for (Map.Entry<String, Double> quoteEntry : quotes.entrySet()) { System.out.println(" 对" + quoteEntry.getKey() + "的价格: " + quoteEntry.getValue()); } } } }
通用思路总结
不管用什么语言,核心逻辑都是这几点:
- 不要依赖固定键名取值,而是遍历JSON对象的所有键值对
- 根据业务需求筛选数据:比如只提取某个计价币种的价格,或者收集所有币种对的完整数据
- 如果API支持参数控制返回结构(比如指定只返回某个币种对),优先用API参数减少数据量,处理起来会更高效
内容的提问来源于stack exchange,提问作者Karl
相关产品推荐
相关产品推荐

