如何在OCL中对两个参数进行排序?

时间:2017-02-02 20:48:12

标签: sorting ocl

我需要通过Surnames和Names之后的两个参数对Persons集合进行排序。我怎样才能在OCL中做这样的事情?

3 个答案:

答案 0 :(得分:1)

sortedBy函数使用其正文中表达的条件对每个元素进行排序,并在每个收集的结果之间建立<关系。

在您的情况下,假设您具有surname属性,以下语句将使用收集的每个姓氏上的c运算符对集合<进行排序(因此{{1}在字符串上):

<

一个想法可能是使用姓氏和名称连接来计算唯一字符串。因此,如果你有:

  • 乔治史密斯
  • Garry Smith
  • George Smath

比较将在“Smith_George”,“Smith_Garry”和“Smath_George”之间进行,并按照词典顺序命令:

  1. George Smath(Sm a th_George)
  2. Garry Smith(Smith_G a rry)
  3. George Smith(smith_G e orge)
  4. 最后,OCL请求(假设c->sortedBy(p | p.surname) surname为现有属性):

    name

    这个小技巧完成了这项工作,但它并不是“完全”对sortedBy的两个参数比较。

答案 1 :(得分:0)

OCL sortedBy(lambda)似乎与Java的排序(比较器)非常不同,显然需要将对象的投影作为排序度量。但是,如果投影是self,则您具有不同的Java功能。因此,如果你sortBy(p | p),排序依赖于&lt;操作p。

为了实现这一点,未来OCL的Eclipse OCL原型引入了一个带有compareTo方法的OclComparable类型,只要您的自定义类型扩展了OclComparable类型,就可以实现所有关系操作。

(具有零()和sum()操作的类似OclSummable通常支持Collection :: sum();例如,String将sum实现为连接。)

答案 2 :(得分:0)

谢谢你激励我。我刚刚提出了http://issues.omg.org/browse/OCL25-213,其文字是:

sortedBy迭代为排序问题提供了一个优雅的解决方案,其中排序度量是排序对象的投影。因此sortedBy(p | p.name)或者仅仅sortedBy(name)很短,避免了涉及两个对象比较的更传统的说明错字的机会。对于具有非平凡指标的大型集合,自然解决方案可能是一种有效的解决方案。

然而,sortedBy解决方案不熟悉,对新手来说很混乱,不适合多键排序,可能需要构建人工复合单键。

一种解决方案可能是提供一个更传统的迭代器,例如sort(p1,p2 | comparison-expression),允许两个键排序:

sort(p1,p2 | let diff1 = p1.key1.compareTo(p2.key1)in 如果diff1&lt;&gt; 0 diff 1 else p1.key2.compareTo(p2.key2)endif)

然而,这种可读性差,错字率很高。

或者,使用元组值度量进行sortedBy可能支持多个键:

sortedBy(元组{第一= KEY1,第二= KEY2})

(元组部件名称的字母顺序决定了优先级。)

(由于sortedBy声明性清晰且紧凑,因此可以针对sort()等效项优化效率低下的小/普通实现。)