2010-09-24 6 views
17

Поддерживает ли groovy любые вложенные обозначения итератора?Как вы делаете вложенные итераторы в groovy?

В приведенном ниже примере я хочу как-то получить значение projectName, которое исходило из внешнего итератора, в мой внутренний итератор. Возможно ли это без сохранения в переменной? В моем примере я получаю ошибку runtuime, что «проект» не найден

it.myprojects.project.each{ 
    println("Project name: " + it.projectName) 
    it.myroles.role.each{ 
     Role role = new Role() 
      role.setName(project.projectName)//how do I get projectName here without storting it in a variable in the outer loop? 
    } 
} 

ответ

17

Он чувствует, как это должно работать:

it.myprojects.project.each{ project-> 
    println("Project name: " + project.projectName) 
    it.myroles.role.each{ 
     Role role = new Role() 
     role.setName(project.projectName) 
    } 
} 

Кроме того, вы можете ссылаться на внешнее замыкание с помощью owner переменной

it.myprojects.project.each{ 
    println("Project name: " + it.projectName) 
    it.myroles.role.each{ 
     Role role = new Role() 
      role.setName(owner.projectName) 
    } 
} 

Однако, я не вижу причин для итерация ролей если все, что вы, кажется, делаете, это создавать новые экземпляры класса Role. Возможно, что-то вроде этого будет проще:

it.myprojects.project.each{ 
    println("Project name: " + it.projectName) 
    it.myroles.role.size().times { 
     Role role = new Role() 
     role.setName(owner.projectName) 
    } 
} 
+0

+1 и выбранный для ответа на вопрос, который я задал – Derek

+0

Вы также можете указать класс именованного итератора, если ваша IDE не может понять это, например: 'it.myprojects.project.each {Project project -> .. «Иногда мне нравится делать это для автозавершения и т. Д. Возможно, это загрязняет ваш код без необходимости для вашей поддержки IDE, но он есть, если вы этого хотите. –

0
it.projectList.each {...} 

?

и этот: http://groovy.codehaus.org/Looping.

Вы зацикливаете на списке, а не на вещи в списке. Кажется, из вашего кода вы зацикливаете на вещи в списке.

+0

эээ, вот мой плохой на syntax..i я на самом деле тянет это из файла XML, и я некоторые теги называют «projectlist» и «rolelist», поэтому список слов просто совпадение – Derek

+0

отредактировал код сейчас, так что нет путаницы – Derek

+0

@derek есть еще проблема? Запустите его в своем любимом отладчике и посмотрите, какой проект ... так же, я заметил, что первый токен в вашем коде - это «он», поэтому кажется, что некоторые вещи происходят вне кода, который вы опубликовали, что вы, возможно, захотите доля. – hvgotcodes

26

Переменные it: не итераторы, это closure параметры. Имя «it» не является сокращенным для «итератора», оно буквально означает «оно», которое используется как имя по умолчанию для однопараметрических замыканий. Тем не менее, вы можете использовать явные (и, таким образом, различные вложенные) имена, как это:

it.myprojects.project.each{ project -> 
    println("Project name: " + project.projectName) 
    project.myroles.role.each{ role-> 
     Role r= new Role() 
     r.setName(project.projectName) 
    } 
} 

На самом деле, я бы посоветовал против использования метода each на всех и использовать реальные петли вместо:

for(project in it.myprojects.project){ 
    println("Project name: " + project.projectName) 
    for(role in project.myroles.role){ 
     Role r= new Role() 
     r.setName(project.projectName) 
    } 
} 

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

+0

ah - это сбивает с толку. Код определенно работает, если вы продолжаете повторное использование «it» вложенным образом. Мне стало ясно только, что было что-то смешное, когда я попытался сделать обратную ссылку на предыдущую. – Derek

+2

@Derek: Похоже, вы занимаетесь программированием в кулинарии, т. Е. Пытаетесь использовать синтаксис, не понимая, что это значит. Неудивительно, что вы в замешательстве. Вам действительно нужно читать закрытие, пока не поймете, что «каждый» - это метод, а не ключевое слово языка, код в фигурных скобках - это закрытие, переданное как параметр методу, а «it» - неявный параметр закрытие, когда оно вызывается каждым методом. –

+1

Я не понимаю, почему явный цикл будет лучше, чем использование каждого метода - это скорее случай личного стиля и предпочтения. – mfloryan

Смежные вопросы