Найти/фильтровать списки с определенной парой ключ-значение из JSON ARRAY (список карт)

У меня есть массив JSON (список карт), похожий на:

def listOfMap = [[TESTCASE:1, METHOD:'CLICK', RESULT:'PASS'], 
      [TESTCASE:2, METHOD:'CLICK', RESULT:'FAIL'], 
      [TESTCASE:3, METHOD:'CLICK', RESULT:'FAIL'], 
      [TESTCASE:4, METHOD:'TYPETEXT', RESULT:'FAIL']]

1) Я хочу получить/отфильтровать/вернуть все списки, которые содержат пары "ключ-значение" "МЕТОД:CLICK" и "РЕЗУЛЬТАТ:НЕУДАЧ"

My output should return 2 lists out of 4: [TESTCASE:2, METHOD:CLICK, RESULT:FAIL], [TESTCASE:3, METHOD:CLICK, RESULT:FAIL]

2) Я хочу получить количество списков, содержащих пары "ключ-значение" "МЕТОД:CLICK" и "РЕЗУЛЬТАТ:НЕУДАЧА"

My output should be : 2 

3) Из приведенного выше списка карт я хочу получить все уникальные/отличающиеся значения для ключа "METHOD"

My output should return unique values of the key method : CLICK, TYPETEXT

person user1523153    schedule 25.01.2018    source источник


Ответы (1)


Фильтрация

В Groovy есть метод с именем Collection.findAll(Closure closure), который отфильтровывает все значения, которые не удовлетворяют предикату (выраженному как замыкание):

println listOfMap.findAll { map -> map.METHOD == 'CLICK' && map.RESULT == 'FAIL' }

// Output: [[TESTCASE:2, METHOD:CLICK, RESULT:FAIL], [TESTCASE:3, METHOD:CLICK, RESULT:FAIL]]

подсчет

Существует также метод DefaultGroovyMethods.count(Iterable<T> self, Closure closure), который ожидает предикат и подсчитывает, сколько элементов ему удовлетворяет:

println listOfMap.count { map -> map.METHOD == 'CLICK' && map.RESULT == 'FAIL' }

// Output: 2

Список уникальных значений из списка карт

Для выбора значения для данного ключа из списка карт вы можете использовать оператор распространения Groovy:

println listOfMap*.METHOD // btw, listOfMap.METHOD will do the same

Этот код переводится как «для каждого элемента внутри listOfMap получите значение для ключа METHOD. На следующем шаге вы можете использовать Collection.unique() для удаления всех дубликатов:

println listOfMap*.METHOD.unique()

// Output: [CLICK, TYPETEXT]

ВНИМАНИЕ: следующий метод не будет работать в скрипте Groovy конвейера Jenkins. В этом случае вам придется использовать Collection.collect(Closure closure) явно:

println listOfMap.collect { map -> map.METHOD }.unique()
person Szymon Stepniak    schedule 25.01.2018