#grails #groovy
#grails #groovy
Вопрос:
Можете ли вы помочь мне определить, что не так в простом удалении с карты ниже (обратите внимание на вывод прямо под ним)?
public class Issue {
...
def allButThis() {
println "allButThis ..."
def all = Issue.list()
println "all is ${all}"
all.remove(this.id)
println "all with ${this.id} removed: ${all}"
return all
}
String toString() {return "${id}: ${title}"}
Когда я запускаю это, я получаю следующие результаты, т. е. элемент 2 не удаляется, как ожидалось
allButThis ...
all is [1: Issue-1, 2: Issue-2, 3: Issue-3]
all with 2 removed: [1: Issue-1, 2: Issue-2, 3: Issue-3]
Насколько я могу судить, это удаление должно сработать, напримерhttp://groovy.codehaus.org/JN1035-Maps, где «удалить» описано на треть ниже по странице.
Я использую Grails 1.3.7.
Спасибо
P.S. Я добавил свой метод toString () (выше), возможно, я обманул себя.
————- обновить ———-
Я удалил свой метод toString () и последовал решению Роба, а именно:
all.remove(this)
println "all with ${this} removed: ${all}"
который выдает:
all is [momentum.Issue : 1, momentum.Issue : 2, momentum.Issue : 3]
all with momentum.Issue : 2 removed: [momentum.Issue : 1, momentum.Issue : 3]
Ответ №1:
def all = Issue.list()
Это список, а не карта.
Итак, чтобы удалить из этого списка:
all.remove(this)
вместо этого.
Комментарии:
1. Роб, я дополнил свой вопрос (внизу) тем, что ты сказал, и это сработало. Можете ли вы сказать мне, почему «это» имеет значение, которое оно имеет, как показано выше?
2. … По-видимому, «this» выполняется по методу string по умолчанию, что имеет смысл. Хотя передача его в all.remove (this) кажется немного странной… конечно, меня обмануло, что он вычислялся до строки, а затем был передан.
3. … Я должен сказать, что ссылка «this», переданная в функцию remove() в списке, была преобразована в ее строковую форму (путем выполнения toString()).
4. Списки получают красивую строку toString, поэтому, когда вы сделали «$ {all}», он вызвал toString за кулисами, который вызывает toString для каждого элемента-члена.
Ответ №2:
this.id
имеет тип Long
и поэтому, если вы хотите удалить n-й элемент, вам нужно преобразовать его в целое число. однако это очень опасно, поскольку запись идентификатора не всегда является n-й записью. удалите этот элемент с помощью .findAll({it.id != this.id})
, было бы больше экономии.
В этом случае я бы рекомендовал вам сделать это следующим образом:
def allExceptThis = Issue.withCriteria {
ne("id", this.id)
}.list();
Комментарии:
1. Спасибо Crudolf. Я немного смущен тем, что «.findAll» является более безопасным, но затем вы порекомендовали .withCriteria . Не могли бы вы, пожалуйста, расширить?
2. извините за путаницу: его не более безопасно использовать
withCriteria
вместоfindAll
. Но я бы исключил «это» не на программном уровне, а на уровне базы данных. Поэтому вам нужно создать запрос, который исключает объект с тем жеid
. Мне больше нравятся withCriteria, чемfindAll
условия в этом случае. Обратите внимание, что, выполняя описанное выше, вам больше не нужно впоследствии манипулировать коллекциями!3. Crudolf, для меня это имеет смысл — сделать это на уровне базы данных. Но все еще не ясно, почему вам нравится .withCriteria лучше, чем .findAll, который я хотел бы понять. Я рад использовать .withCriteria, просто хотел бы понять, почему он отличается от findAll. Это просто более понятный способ выполнения кода, поэтому он вам нравится больше? Спасибо
4.
withCriteria
подготовит и выполнит SQL-запрос.findAll
является частью collection API и будет фильтровать на программном уровне (в существующей коллекции).