groovy / grails, я не могу удалить с карты

#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 и будет фильтровать на программном уровне (в существующей коллекции).