如何按自定义顺序对列表进行排序?

时间:2015-07-31 09:06:15

标签: sorting grails groovy

我想使用Groovy按定义的顺序对列表进行排序

def ls = [ 'sperson_firstname', 'a_id', 'a_name', 'scontact_street', 'scontact_email',  'sperson_nationality', 'scontact_tel', 'sperson _birthday', 'sperson_lastname', 'scontact_fax']

排序后应按如下方式排序:

 ls = ['a_id', 'a_name', 'sperson_firstname', 'sperson_lastname', 'sperson _birthday','sperson_nationality','scontact_street', 'scontact_email',  'scontact_tel', 'scontact_fax']

这意味着我定义的订单应首先排序前缀,如

[a , sperson, scontact]

然后,对于每个前缀,应使用定义的顺序对其后缀进行排序

e.g。前缀 sperson 应该排序为

['sperson_firstname', 'sperson_lastname', 'sperson _birthday','sperson_nationality']
前缀 scontact

应该与

类似
['scontact_street', 'scontact_email',  'scontact_tel', 'scontact_fax']

我试过了

def sortOrder = ["a","sperson","scontact"]
ls.sort{ls -> sortOrder.indexOf(ls.split("_")[0]) }

但这只能解决前缀排序......

2 个答案:

答案 0 :(得分:1)

您可以执行您正在执行的操作并将其扩展为前缀:

List prefixOrder = ['a' , 'sperson', 'scontact']
Map suffixOrdersByPrefix = [
    a: [...],
    b: [...],
    c: [...]
]
def indexOfComparator = { list, a, b -> 
   list.indexOf(a).compareTo(list.indexOf(b)) 
}
def prefixComparator = { a, b -> 
   indexOfComparator(prefixOrder, a, b)
}
def suffixComparator = { prefix, a, b ->
   indexOfComparator(suffixOrdersByPrefix[prefix], a, b)
}

l.sort { a, b ->
    List<String> aTokens = a.tokenize('_'),
        bTokens = b.tokenize('_')
    prefixComparator(aTokens.first(), bTokens.first()) ?:
        suffixComparator(aTokens.first(), aTokens.last(), bTokens.last())
}

比较前缀,如果相等(即比较返回0),则比较后缀。您可以使用......嗯,地图:)来映射每个后缀的顺序。

答案 1 :(得分:0)

Your approach wasn't that far off. I just used a two-dimensional array (actually a list of lists I guess), where the first element is the prefix and the following are the suffixes for that index. Then the order is just a weighted prefix score plus the suffix score.

def ls = ['sperson_firstname', 'a_id', 'a_name', 'scontact_street', 'scontact_email',  'sperson_nationality', 'scontact_tel', 'sperson_birthday', 'sperson_lastname', 'scontact_fax']

def sortOrder = [
    ['a','id','name'],
    ['sperson','firstname','lastname','birthday','nationality'],
    ['scontact','street','email','tel','fax']
]

ls.sort{item ->
    def preIndex = sortOrder.collect{it[0]}.indexOf(item.split('_')[0])
    def postIndex = sortOrder[preIndex][1..(sortOrder[preIndex].size-1)].indexOf(item.split('_')[1])
    return (preIndex * 10) + postIndex
}

assert ['a_id', 'a_name', 'sperson_firstname', 'sperson_lastname', 'sperson_birthday', 'sperson_nationality', 'scontact_street', 'scontact_email', 'scontact_tel', 'scontact_fax'] == ls