2017-02-02 4 views

ответ

1

Функция sortedBy сортирует элементы, используя критерии, выраженные в ее теле, и связь между каждым собранным результатом <.

В вашем случае, если предположить, что у вас есть атрибут surname, следующий оператор будет сортировать коллекцию c с помощью оператора < на каждой фамилии собрались (так < на струнах):

c->sortedBy(p | p.surname) 

идея может чтобы вычислить уникальную строку, используя фамилию и имя, конкатенированное с ним. Таким образом, если у вас есть:

  • George Smith
  • Garry Smith
  • Джордж SMath

Сравнение будет сделано между "Smith_George", "Smith_Garry" и "Smath_George" и будет заказал, после лексикографического порядка, чтобы:

  1. Джорджа SMath (Sm т h_George)
  2. Garry Smith (Smith_G RRY)
  3. Джордж Смит (smith_G е огр)

Наконец, запрос OCL будет (при условии surname и name как существующие атрибуты):

c->sortedBy(p | p.surname + '_' + p.name) 

Этот небольшой трюк выполняет эту работу, но это не «точно» сравнение двух параметров для sortedBy.

+0

мне кажется, что это решение не будет работать во всех случаях, Мне нужно что-то унив ersal. Это решение будет неправильным, если у нас есть, например, две даты. Например, дата начала проекта и дата завершения проекта. Что я могу использовать в таких случаях? – DM14

+0

Как я уже сказал, это решение работало в вашем конкретном случае, используя имя/фамилию, это будет использовать лексикографический порядок. Я не уверен, но я не думаю, что функция OCL sortedBy может выполнять этот поиск по двум критериям. В других случаях необходимо найти еще один трюк, в примере с датой начала и окончания вы можете вычислить время, затрачиваемое каждым проектом, с использованием даты окончания/начала и сортировки по этим критериям. В противном случае, переводя дату в формате yyy-mm-dd (со знаковым 0 obvioulsy), должен работать трюк с лексикографическим порядком. –

0

OCL sortedBy (lambda), по-видимому, сильно отличается от сорта Java (компаратора), по-видимому, требуя проекции объектов в качестве метрики для сортировки. Однако, если проекция является «я», у вас есть другая функциональность Java. Поэтому, если вы отсортировалиBy (p | p), сортировка зависит от операции < для p.

Для облегчения этого прототип Eclipse OCL будущего OCL вводит тип OclComparable с методом compareTo, позволяющим реализовать все реляционные операции, если ваш настраиваемый тип расширяет тип OclComparable.

(Аналогичный OclSummable с нуля() и сумма() действует поддерживает Collection :: сумму() в общем,., Например, строка реализует сумму в виде конкатенации)

0

Спасибо вы вдохновили меня. Я только что поднял http://issues.omg.org/browse/OCL25-213, текст которого:

Итерация sortedBy обеспечивает элегантное решение проблемы сортировки, в которой метрика сортировки является проекцией отсортированного объекта. Таким образом, sortedBy (p | p.name) или просто sortedBy (имя) является коротким и позволяет избежать опечаток из более условного изложения, включающего сравнение двух объектов.Естественное решение вполне может быть эффективным для больших коллекций с нетривиальными метриками.

Однако решение sortedBy не знакомо и настолько запутанно для новичков и не подходит для многокварной сортировки, для чего может потребоваться построить отдельный ключ из искусственного компаунда.

Одним из решений может быть, чтобы обеспечить более обычного итератора, такие как вид (p1, p2 | сравнение выражение), допускающие два ключа сортировки:

рода (p1, p2 | пусть diff1 = p1.key1.compareTo (p2.key1) в если diff1 <> 0 разн 1 еще p1.key2.compareTo (p2.key2) ENDIF)

Однако это имеет плохую читаемость и широкие возможности для опечаток.

В качестве альтернативы sortedBy с кортежем-значной метрикой может поддерживать несколько ключей, как:

sortedBy (набор {первого = key1, второй = key2})

(алфавитный порядок названий кортежа части определяет приоритет.)

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

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

  • Нет связанных вопросов^_^