数组处理案例收集

本文介绍了一种在一维数组中,对于包含多个对象的数组如何根据特定字段进行排序的方法。通过PHP代码示例展示了如何使用array_multisort函数对数组中的对象按距离(distancenum)属性进行升序排列。

1,在一维数组中有多组数组对象时的排序案例

"data": [{
		"id": "60",
		"h_f_id": "10",
		"latitude": "30.257360",
		"longitude": "120.201750",
		"h_f_name": "医院",
		"distance": ">100Km",
		"distancenum": 1061670.7
	}, {
		"id": "61",
		"h_f_id": "10",
		"latitude": "30.300090",
		"longitude": "120.316170",
		"h_f_name": "医院",
		"distance": ">100Km",
		"distancenum": 1072167.1
	}, {
		"id": "62",
		"h_f_id": "10",
		"latitude": "30.284420",
		"longitude": "120.167820",
		"h_f_name": "医院",
		"distance": ">100Km",
		"distancenum": 1062063.6
	}, {
		"id": "63",
		"h_f_id": "10",
		"latitude": "30.148760",
		"longitude": "120.068820",
		"h_f_name": "医院",
		"distance": ">100Km",
		"distancenum": 1044317.1
	}]

需求:我需要以distancenum(距离)为标准来进行重新对整个数组进行排序。也就是以数组中的一条记录值进行整个数据组的排序

处理方法:以上数据假设是$result中的数据

$flag = array();
foreach ($result as $v) {
 $flag[] = $v['distancenum'];
   }
  array_multisort($flag, SORT_ASC, $result);

array_multisort的使用

<think> 我们需要处理JsonNode中的数组。通常,在使用Jackson库处理JSON时,JsonNode可以表示数组(即ArrayNode)。以下我们将展示如何遍历、修改和过滤JsonNode数组。 主要步骤: 1. 将JsonNode转换为ArrayNode(如果它是数组类型) 2. 遍历数组中的每个元素 3. 修改数组元素 4. 过滤数组 5. 创建新的数组 为了处理JsonNode数组,我们需要使用Jackson库。确保项目中包含以下依赖(Maven): ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> <!-- 使用最新版本 --> </dependency> ``` ## 示例代码 以下是一个完整的示例,展示如何读取JSON数组,遍历、修改、过滤和创建新的数组: ```java import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; import java.util.Iterator; public class JsonNodeArrayExample { public static void main(String[] args) throws IOException { // JSON字符串示例 String jsonArrayStr = "[ " + "{\"name\": \"Alice\", \"age\": 25}," + "{\"name\": \"Bob\", \"age\": 30}," + "{\"name\": \"Charlie\", \"age\": 35}" + "]"; ObjectMapper mapper = new ObjectMapper(); JsonNode rootNode = mapper.readTree(jsonArrayStr); // 1. 检查是否为数组 if (rootNode.isArray()) { ArrayNode arrayNode = (ArrayNode) rootNode; // 2. 遍历数组 System.out.println("=== 原始数组 ==="); for (JsonNode node : arrayNode) { System.out.println(node); } // 3. 修改数组:给每个人的年龄加1 System.out.println("\n=== 修改后的数组(年龄加1) ==="); for (JsonNode node : arrayNode) { if (node.isObject()) { ObjectNode objNode = (ObjectNode) node; int age = objNode.get("age").asInt(); objNode.put("age", age + 1); } System.out.println(node); } // 4. 过滤数组:只保留年龄大于等于31的人 Iterator<JsonNode> it = arrayNode.iterator(); while (it.hasNext()) { JsonNode node = it.next(); if (node.get("age").asInt() < 31) { it.remove(); } } System.out.println("\n=== 过滤后(年龄>=31) ==="); System.out.println(arrayNode); // 5. 创建新的数组 ArrayNode newArray = mapper.createArrayNode(); ObjectNode person1 = mapper.createObjectNode(); person1.put("name", "David"); person1.put("age", 40); newArray.add(person1); newArray.addAll(arrayNode); // 将过滤后的数组加入新数组 System.out.println("\n=== 新数组 ==="); System.out.println(newArray); } } } ``` ## 代码解释 ### 1. 解析JSON数组 ```java JsonNode rootNode = mapper.readTree(jsonArrayStr); ``` 使用ObjectMapper将JSON字符串解析为JsonNode。如果JSON字符串是一个数组,则rootNode将是一个ArrayNode。 ### 2. 遍历数组 ```java for (JsonNode node : arrayNode) { System.out.println(node); } ``` 因为ArrayNode实现了Iterable接口,可以直接使用增强for循环遍历。 ### 3. 修改数组元素 ```java ObjectNode objNode = (ObjectNode) node; int age = objNode.get("age").asInt(); objNode.put("age", age + 1); ``` 将每个元素转换为ObjectNode(因为元素是对象),然后修改age字段的值。 ### 4. 过滤数组 ```java Iterator<JsonNode> it = arrayNode.iterator(); while (it.hasNext()) { JsonNode node = it.next(); if (node.get("age").asInt() < 31) { it.remove(); } } ``` 使用迭代器遍历数组,并通过迭代器的remove方法移除不符合条件的元素(年龄小于31)。 ### 5. 创建新数组 ```java ArrayNode newArray = mapper.createArrayNode(); ObjectNode person1 = mapper.createObjectNode(); person1.put("name", "David"); person1.put("age", 40); newArray.add(person1); newArray.addAll(arrayNode); ``` 使用ObjectMapper创建ArrayNode和ObjectNode,然后添加元素。 ## 输出示例 ``` === 原始数组 === {"name":"Alice","age":25} {"name":"Bob","age":30} {"name":"Charlie","age":35} === 修改后的数组(年龄加1) === {"name":"Alice","age":26} {"name":"Bob","age":31} {"name":"Charlie","age":36} === 过滤后(年龄>=31) === [{"name":"Bob","age":31},{"name":"Charlie","age":36}] === 新数组 === [{"name":"David","age":40},{"name":"Bob","age":31},{"name":"Charlie","age":36}] ``` ## 高级操作:使用Stream API处理ArrayNode 如果你使用Java 8+,可以使用Stream API来处理ArrayNode(需要先转换为Stream): ```java import com.fasterxml.jackson.databind.node.JsonNodeFactory; import java.util.stream.StreamSupport; // 将ArrayNode转换为Stream<JsonNode> ArrayNode arrayNode = ...; StreamSupport.stream(arrayNode.spliterator(), false) .filter(node -> node.get("age").asInt() >= 30) .forEach(System.out::println); // 或者收集回ArrayNode ArrayNode filteredArray = JsonNodeFactory.instance.arrayNode(); StreamSupport.stream(arrayNode.spliterator(), false) .filter(node -> node.get("age").asInt() >= 30) .forEach(filteredArray::add); ``` ## 注意事项 - 在修改ArrayNode时,注意如果JsonNode是从不可变配置中解析出来的,可能会抛出异常(默认是可变的)。 - 使用迭代器删除元素是安全的,但在遍历过程中修改元素内容(如修改字段)也是允许的。 ## 结论 JsonNode(特别是ArrayNode)提供了灵活的方法来处理JSON数组。通过结合Jackson库和Java的集合操作,我们可以高效地遍历、修改、过滤和创建JSON数组。 --- ### §§相关问题§§: 1. 如何将Java对象数组转换为JsonNode数组? 2. 如何使用JsonPath处理复杂的JSON数组查询? 3. 如何合并多个JsonNode数组? 4. 如何处理嵌套的JSON数组数组中的数组)? </think> # 深入解析 JsonNode 数组处理 Jackson 库的 `JsonNode` 是处理 JSON 数据的核心类,尤其在处理数组时非常强大。下面我将详细介绍如何使用 `JsonNode` 高效处理 JSON 数组。 ## 核心处理代码示例 ```java import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; public class JsonNodeArrayProcessor { private static final ObjectMapper mapper = new ObjectMapper(); public static void main(String[] args) throws Exception { // 示例 JSON 数组 String jsonArray = """ [ {"id": 1, "name": "Alice", "age": 30, "active": true}, {"id": 2, "name": "Bob", "age": 25, "active": false}, {"id": 3, "name": "Charlie", "age": 35, "active": true} ]"""; // 1. 解析 JSON 数组 JsonNode rootNode = mapper.readTree(jsonArray); System.out.println("原始数组: " + rootNode); // 2. 遍历数组元素 System.out.println("\n遍历元素:"); for (JsonNode node : rootNode) { String name = node.get("name").asText(); int age = node.get("age").asInt(); System.out.println(name + " (" + age + ")"); } // 3. 过滤数组 System.out.println("\n过滤活跃用户:"); ArrayNode activeUsers = mapper.createArrayNode(); rootNode.forEach(user -> { if (user.get("active").asBoolean()) { activeUsers.add(user); } }); System.out.println(activeUsers); // 4. 修改数组内容 System.out.println("\n添加新属性:"); ObjectNode updatedNode = (ObjectNode) rootNode.get(0); updatedNode.put("department", "Engineering"); System.out.println(rootNode); // 5. 转换为 Java 集合 System.out.println("\n转换为 Java List:"); List<User> userList = mapper.convertValue(rootNode, new TypeReference<List<User>>() {}); userList.forEach(System.out::println); } static class User { private int id; private String name; private int age; private boolean active; // Getters, setters, toString... } } ``` ## JsonNode 数组处理详解 ### 1. 解析数组 ```java JsonNode rootNode = mapper.readTree(jsonArray); ``` - 使用 `ObjectMapper` 的 `readTree()` 方法直接将 JSON 字符串解析为 `JsonNode` - 当 JSON 以 `[` 开头时,解析结果将是 `ArrayNode` 类型 ### 2. 遍历数组 ```java for (JsonNode node : rootNode) { // 处理每个元素 } ``` - `ArrayNode` 实现了 `Iterable<JsonNode>` 接口,可直接用于 for-each 循环 - 使用 `get(fieldName)` 访问对象属性 - 使用 `asText()`、`asInt()` 等方法获取值 ### 3. 过滤数组元素 ```java ArrayNode filtered = mapper.createArrayNode(); rootNode.forEach(element -> { if (condition) { filtered.add(element); } }); ``` - 使用 `forEach()` 方法遍历数组 - 通过 `createArrayNode()` 创建新数组 - 使用 `add()` 方法添加符合条件的元素 ### 4. 修改数组内容 ```java ObjectNode firstElement = (ObjectNode) rootNode.get(0); firstElement.put("newField", "value"); ``` - 使用 `get(index)` 获取特定位置的元素 - 将 `JsonNode` 转换为 `ObjectNode` 进行修改 - 使用 `put()` 添加或修改字段 ### 5. 数组转换为 Java 集合 ```java List<User> users = mapper.convertValue(rootNode, new TypeReference<List<User>>() {}); ``` - 使用 `convertValue()` 方法直接转换为 Java 集合 - 需要指定泛型类型 `TypeReference` - POJO 类应有无参构造函数和 getter/setter ## 高级操作技巧 ### 1. 流式处理数组 ```java List<String> names = StreamSupport.stream(rootNode.spliterator(), false) .map(node -> node.get("name").asText()) .collect(Collectors.toList()); ``` ### 2. 查找特定元素 ```java Optional<JsonNode> bob = StreamSupport.stream(rootNode.spliterator(), false) .filter(node -> "Bob".equals(node.get("name").asText())) .findFirst(); ``` ### 3. 合并多个数组 ```java ArrayNode merged = mapper.createArrayNode(); merged.addAll((ArrayNode) array1); merged.addAll((ArrayNode) array2); ``` ### 4. 数组排序 ```java List<JsonNode> sorted = StreamSupport.stream(rootNode.spliterator(), false) .sorted(Comparator.comparingInt(node -> node.get("age").asInt())) .collect(Collectors.toList()); ArrayNode sortedArray = mapper.createArrayNode(); sorted.forEach(sortedArray::add); ``` ## 实用工具类 ```java import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import java.util.List; import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class JsonArrayUtils { private static final ObjectMapper mapper = new ObjectMapper(); // 查找单个元素 public static Optional<JsonNode> findFirst(ArrayNode array, Predicate<JsonNode> condition) { return StreamSupport.stream(array.spliterator(), false) .filter(condition) .findFirst(); } // 过滤数组 public static ArrayNode filter(ArrayNode array, Predicate<JsonNode> condition) { ArrayNode result = mapper.createArrayNode(); StreamSupport.stream(array.spliterator(), false) .filter(condition) .forEach(result::add); return result; } // 映射转换 public static <T> List<T> mapToObjects(ArrayNode array, Class<T> targetType) { return StreamSupport.stream(array.spliterator(), false) .map(node -> mapper.convertValue(node, targetType)) .collect(Collectors.toList()); } // 分组统计 public static ArrayNode groupBy(ArrayNode array, String field) { ArrayNode result = mapper.createArrayNode(); StreamSupport.stream(array.spliterator(), false) .collect(Collectors.groupingBy(node -> node.get(field).asText())) .forEach((key, nodes) -> { ObjectNode group = mapper.createObjectNode(); group.put(field, key); group.set("count", mapper.valueToTree(nodes.size())); group.set("items", mapper.valueToTree(nodes)); result.add(group); }); return result; } } ``` ## 性能优化建议 1. **避免重复解析**:解析 JSON 是相对昂贵的操作,尽量只解析一次 2. **使用树模型替代数据绑定**:当数据结构变化频繁时,树模型更灵活 3. **批量处理**:对于大型数组,使用流式处理避免内存溢出 4. **自定义序列化**:对于性能关键场景,实现自定义 `JsonSerializer` 5. **使用 JSON Pointer**:快速定位特定元素 ```java JsonNode specificNode = rootNode.at("/2/name"); // 获取第三个元素的name字段 ``` ## 常见问题解决方案 ### 问题1:处理嵌套数组 ```json [ { "id": 1, "name": "Department A", "employees": [ {"name": "Alice", "role": "Manager"}, {"name": "Bob", "role": "Developer"} ] } ] ``` 处理代码: ```java JsonNode departments = mapper.readTree(json); departments.forEach(dept -> { ArrayNode employees = (ArrayNode) dept.get("employees"); employees.forEach(emp -> { String name = emp.get("name").asText(); String role = emp.get("role").asText(); // 处理员工数据... }); }); ``` ### 问题2:处理混合类型数组 ```json [ "text", 42, {"name": "object"}, [1, 2, 3] ] ``` 处理代码: ```java rootNode.forEach(element -> { if (element.isTextual()) { // 处理文本 } else if (element.isNumber()) { // 处理数字 } else if (element.isObject()) { // 处理对象 } else if (element.isArray()) { // 处理嵌套数组 } }); ``` ### 问题3:数组分页 ```java public ArrayNode paginate(ArrayNode array, int page, int size) { int fromIndex = page * size; int toIndex = Math.min(fromIndex + size, array.size()); ArrayNode pageNodes = mapper.createArrayNode(); for (int i = fromIndex; i < toIndex; i++) { pageNodes.add(array.get(i)); } return pageNodes; } ``` ### 问题4:数组差异比较 ```java public ArrayNode diff(ArrayNode array1, ArrayNode array2) { Set<JsonNode> set1 = new HashSet<>(); StreamSupport.stream(array1.spliterator(), false).forEach(set1::add); ArrayNode diff = mapper.createArrayNode(); StreamSupport.stream(array2.spliterator(), false) .filter(node -> !set1.contains(node)) .forEach(diff::add); return diff; } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itxiaolong3

打赏可以,但别打我就行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值