在Python开发中,我们经常需要处理接口返回的JSON数据或者本地存储的JSON文件,其中很多场景需要对包含日期字段的对象数组进行排序。如果日期字段是嵌套在多层结构中的,就需要用到深度排序的逻辑。下面我们一步步讲解实现方法。

核心思路
要实现根据特定日期字段对JSON对象数组进行深度排序,核心需要解决三个问题:第一是找到嵌套在任意层级的日期字段,第二是把日期字符串转换为可比较的时间对象,第三是自定义排序规则完成数组排序。
日期字段的提取
如果JSON结构是嵌套的,比如日期字段在data->info->create_time这样的路径下,我们需要先编写通用的路径解析方法,根据传入的字段路径获取对应的值。我们可以用列表存储字段路径,递归遍历JSON对象获取目标值。
日期字符串转换
JSON中的日期通常是字符串格式,比如2024-05-20 14:30:00或者2024/05/20,需要将其转换为datetime对象才能进行比较排序。Python的datetime模块提供了strptime方法可以完成这个转换。
完整实现代码
下面是一段可直接运行的完整代码,支持自定义日期字段路径,处理嵌套JSON的对象数组排序:
import json
from datetime import datetime
def get_nested_value(obj, path):
"""根据路径获取嵌套对象中的值"""
current = obj
for key in path:
if isinstance(current, dict) and key in current:
current = current[key]
else:
return None
return current
def parse_date(date_str, date_formats):
"""尝试多种格式解析日期字符串"""
for fmt in date_formats:
try:
return datetime.strptime(date_str, fmt)
except ValueError:
continue
return None
def sort_json_array_by_date(json_array, date_field_path, date_formats=None):
"""
对JSON对象数组按指定日期字段深度排序
:param json_array: 待排序的JSON对象数组
:param date_field_path: 日期字段路径,比如['data','info','create_time']
:param date_formats: 日期字符串支持的格式列表,默认支持常见格式
:return: 排序后的数组
"""
if date_formats is None:
date_formats = [
'%Y-%m-%d %H:%M:%S',
'%Y-%m-%d',
'%Y/%m/%d %H:%M:%S',
'%Y/%m/%d'
]
# 提取每个元素的日期并转换为datetime对象
def get_sort_key(item):
date_str = get_nested_value(item, date_field_path)
if date_str is None:
# 没有日期字段的元素放到最后
return datetime.max
date_obj = parse_date(str(date_str), date_formats)
return date_obj if date_obj else datetime.max
# 按日期升序排序,reverse=True为降序
return sorted(json_array, key=get_sort_key)
# 测试示例
if __name__ == '__main__':
# 嵌套结构的JSON对象数组
test_data = [
{
"id": 1,
"data": {
"info": {
"create_time": "2024-05-18 10:00:00",
"name": "测试1"
}
}
},
{
"id": 2,
"data": {
"info": {
"create_time": "2024-05-20 14:30:00",
"name": "测试2"
}
}
},
{
"id": 3,
"data": {
"info": {
"create_time": "2024-05-19 09:15:00",
"name": "测试3"
}
}
}
]
# 日期字段路径
target_path = ['data', 'info', 'create_time']
# 执行排序
sorted_result = sort_json_array_by_date(test_data, target_path)
# 输出排序结果
print(json.dumps(sorted_result, ensure_ascii=False, indent=2))
代码说明
上述代码中,get_nested_value方法负责根据传入的路径列表获取嵌套对象中的值,支持任意层级的字段提取。parse_date方法支持多种常见的日期格式解析,避免因为日期格式不统一导致转换失败。sort_json_array_by_date是核心排序方法,通过自定义排序键,把每个元素的日期转换为datetime对象后作为排序依据,没有日期字段的元素会被放到数组末尾。
注意事项
- 如果日期字段的格式比较特殊,可以在调用
sort_json_array_by_date时传入自定义的date_formats参数,添加对应的格式字符串。 - 如果需要降序排序,只需要在
sorted函数中添加reverse=True参数即可。 - 如果JSON数组中的元素结构不一致,部分元素没有目标日期字段,代码会默认把这些元素放到排序结果的最后,不会抛出异常。