自定义排序Groovy JSONArray - 自定义值首先,然后按字母顺序

时间:2015-09-25 18:54:27

标签: arrays json sorting grails groovy

我有一个JSONArray中的静态值列表。这是我的示例数组:

JSONArray json = new JSONArray()

json = ["B", "E", "C", "Z", "A", "X", "F", "H"]

我需要以自定义方式对这个json数组进行排序。我需要把" E"首先," F"第二,然后按字母顺序对其余部分进行排序。

我希望我的最终结果是:

json = ["E", "F", "A", "B", "C", "H", X", "Z"]

Groovy具有基本的排序功能,我可以按字母顺序或按字母顺序反向排序:

json.sort()

json.reverse()

我正在寻找一种简单的方法来进行自定义排序。

2 个答案:

答案 0 :(得分:0)

如果你定义了自己的排序方法,你可以使用闭包,但是你实际要求的是使用一点点正常排序的一些数组拆分。

json.findAll{it = 'E'} + json.findAll{it = 'F'} + json.findAll{!(it in ['E', 'F'])}.sort()

如果你担心循环json 3次的效率,你可以迭代你的json一次,然后将它添加到不同的数组中。

以下示例有点发烧友。 inject方法将遍历一个集合,在每次迭代之间传递一个值(在我们的例子中是一个包含3个列表的列表。第一个列表将保存我们的E,第二个列表将保存我们的F' s和第三个列表排序后我们使用.flatten()将3个列表转换回一个列表。

List organizedList = json.inject([[],[],[]]) {List<List> result, String jsonValue ->
    select(jsonValue) {
        case 'E':
            result.get(0).add(jsonValue) // Could have just added 'E' but I like symmetry
            break;
        case 'F':
            result.get(1).add(jsonValue)
            break;
        default:
            result.get(2).add(jsonValue)
    }
    return result // Gets passed to each iteration over json
}
organizedList.get(2).sort() // sort on a list modifies the original list 
organizedList.flatten()

也可以使用带有闭包的sort来定义自己的排序;但正如你所看到的,它并不容易流动。

json.sort {String a, String b ->  
    if (a = b) return 0 // For efficiency's sake

    def letterFirst = {String priority -> // Closure to help sort against a hardcoded value
        if (a = priority) return 1
        if (b = priority) return -1    
        return 0
    }

    def toReturn = letterFirst('E')
    if (!toReturn) toReturn = letterFirst('F') // groovy evaluates 0 as false
    if (!toReturn) toReturn = a <=> b
    return toReturn 
}

答案 1 :(得分:0)

在我5分钟的实验中,我使用了重量:

def json = ["B", "E", "C", "Z", "A", "X", "F", "H"]
def weights = [ E:10, F:9 ]

json.sort{
  it.charAt( 0 ) - ( weights[ it ] ?: 0 )
}

assert '[E, F, A, B, C, H, X, Z]' == json.toString()

您可能希望包含一些错误检查