Подтвердить что ты не робот

Инструкция eachWithIndex groovy

Я новичок в groovy, и я столкнулся с некоторыми проблемами, понимающими инструкции each{} и eachwithindex{} в groovy.

Действительно ли методы each и eachWithIndex? Если да, то какие аргументы они берут?

В документации groovy приведен этот пример:

def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" } //prints each index and number

Ну, я вижу, что numbers - это массив. Что такое num и idx в приведенном выше утверждении? Что делает оператор ->?

Я знаю, что $idx и $num печатает значение, но как это связано с тем, что idx и num автоматически связаны с индексом и содержимым массива? Какова логика этого? Пожалуйста, помогите.

4b9b3361

Ответ 1

Это простые методы, но они следуют довольно конкретному шаблону - они принимают Closure в качестве своего последнего аргумента. Закрытие - это часть функциональности, которую вы можете обойти и вызвать, когда это применимо.

Например, метод eachWithIndex может выглядеть примерно так:

void eachWithIndex(Closure operation) {
    for (int i = 0; this.hasNext(); i++) {
        operation(this.next(), i); // Here closure passed as parameter is being called
    }
}

Этот подход позволяет строить общие алгоритмы (например, итерации по элементам) и изменять конкретную логику обработки во время выполнения, передавая разные блокировки.

Что касается части параметров, как вы видите в примере выше, мы вызываем замыкание (operation) двумя параметрами - текущим элементом и текущим индексом. Это означает, что каждый метод whithIndex ожидает получить не только закрытие, но и тот, который будет принимать эти два параметра. Из проспективного синтаксиса определяются параметры во время определения закрытия следующим образом:

{ elem, index ->
    // logic 
}

Итак, -> используется для разделения аргументов части определения закрытия из его логики. Когда замыкание принимает только один аргумент, его определение параметра может быть опущено, а затем параметр будет доступен в пределах области закрытия с именем it (неявное имя для первого аргумента). Например:

[1,2,3].each {
    println it
} 

Его можно было бы переписать следующим образом:

[1,2,3].each({ elem ->
    println elem
})

Как вы видите, язык Groovy добавляет некоторый синтаксический сахар, чтобы сделать такие конструкции более красивыми.

Ответ 2

each и eachWithIndex, среди многих других, принимают так называемый Closure как аргумент. Закрытие - это всего лишь фрагмент кода Groovy, заключенный в скобки {}. В коде с массивом:

def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" }

существует только один аргумент (замыкание или, точнее, функция), обратите внимание, что в Groovy () скобки иногда бывают необязательными. num и idx являются просто необязательными псевдонимами для аргументов закрытия (функции), когда нам нужен только один аргумент, это эквивалентно (it - неявное имя первого аргумента закрытия, очень удобно):

def numbers = [ 5, 7, 9, 12 ]
numbers.each {println "$it" }

Литература:

Ответ 3

Обычно, если вы используете функциональный язык программирования, например Groovy, вам следует избегать использования each и eachWithIndex, поскольку они побуждают вас изменять состояние в закрытии или делать вещи, которые имеют побочные эффекты.

Если возможно, вы можете выполнять свои операции с использованием других методов сбора данных groovy, таких как .collect или .inject или findResult и т.д.

Однако, чтобы использовать их для своей проблемы, то есть распечатать элементы списка с их индексом, вам нужно будет использовать метод withIndex в исходной коллекции, который преобразует коллекцию в коллекцию пар [element, index ]

Например,

println(['a', 'b', 'c'].withIndex())

Ответ 4

EachWithIndex можно использовать следующим образом:

package json
import groovy.json.*
import com.eviware.soapui.support.XmlHolder
def project = testRunner.testCase.testSuite.project
def testCase = testRunner.testCase;

def strArray = new String[200]
//Response for a step you want the json from
def response = context.expand('${Offers#Response#$[\'Data\']}').toString()

def json = new JsonSlurper().parseText(response)

//Value you want to compare with in your array
def offername = project.getPropertyValue("Offername")

log.info(offername)

Boolean flagpresent = false
Boolean flagnotpresent = false

strArray = json.Name

def id = 0;

//To find the offername in the array of offers displayed
strArray.eachWithIndex
{
    name, index ->
    if("${name}" != offername)
    {
        flagnotpresent= false;

    }
    else
    {
        id = "${index}";
        flagpresent = true;
        log.info("${index}.${name}")
        log.info(id)
    }

}