乐趣区

像sql中的order语句来对数组排序

经常遇到这样的场景,要根据不同字段的排序条件,输出符合要求的列表信息。经常我们把排序的逻辑写在 sql 语句中。如今,我有需要去验证数据的排序是否符合要求,所以要通过给你的数据,去验证它的排序逻辑。单个字段的排序还好,如果是多个字段,就会麻烦一些。晚上的思路比较活跃。果果和果妈已熟睡。代码如下,可以像 sql 一样的 order 语句,来对数组进行排序。
算是重复造轮子吧​。

#!/usr/bin/python3
​
import pprint
​
def magic_sort(data=[{}], order="id desc",delimiter=";"):
    '''
    @param    data    list        item is a dict  
    @param    order   string      order like sql "id desc; status asc; field(id,2,-1,1)"
    @return   data    list        sorted data
    @todo   order by field
    '''
    orderArr = []
    for item in order.lower().split(delimiter):
        if "field" in item:
            orderArr.append(item.strip()[6:-1].replace("","").split(','))  # ['id','2','-1','1']
        else:
            orderArr.append(item.strip().split())
    orderArr.reverse()     # 先排最后的字段,第一个字段,最后排序
    size = len(data)
    for o in orderArr:
        key = int(o[0]) if o[0].isdigit() else o[0] # 如果 key 是数字字符,返回整数
        if len(o) < 2:
            ad = 'asc'
        elif len(o) == 2:
            ad = o[1]
        else:
            # order by field
            data = sort_by_field(data,o)
            continue
​
        for i in range(size):
            for j in range(size-i-1):
                if (ad == 'desc' and data[j][key] < data[j+1][key]) or (ad == 'asc' and data[j][key] > data[j+1][key]):
                    data[j],data[j+1] = data[j+1],data[j]
    return data
​
def sort_by_field(data,order):
    field = order[0] # 字段
    sort  =  order[1:] # 字段的排序 ['1','3','-1']
    res = []
    last = []
    for o in sort:
        for item in data:
            if str(item[field]) == o:
                res.append(item)
    for item in data:
        if str(item[field]) not in sort:
            last.append(item)
    return res+last
​
​
​
​
def _test_sort(params):
    for param in params:
        res = magic_sort(param['data'],param['order'])
        myprint(res)
    
def myprint(param):
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(param)
    
if __name__ == '__main__':
    data = [{"id":1,"status":3,"age":12},
            {"id":2,"status":1,"age":13},
            {"id":2,"status":2,"age":14},
            {"id":2,"status":3,"age":14},
            {"id":4,"status":2,"age":15},
    ]
    order = "id desc; field(status,1,3,2)"
    #order = "field(status,1,3,2)"
    params = [{"data":data,"order":order}]
    ll = [[1,3,2,5],
            [3,2,3,5],
            [3,1,4,3],
            [2,3,4,2],
            [3,0,4,1],
            [5,3,1,5],
            ]
    llorder = "0 desc;1 asc;2 desc;3 desc"
    params.append({"data":ll,"order":llorder})
    _test_sort(params)
​
退出移动版