我需要通过Surnames和Names之后的两个参数对Persons集合进行排序。我怎样才能在OCL中做这样的事情?
答案 0 :(得分:1)
sortedBy
函数使用其正文中表达的条件对每个元素进行排序,并在每个收集的结果之间建立<
关系。
在您的情况下,假设您具有surname
属性,以下语句将使用收集的每个姓氏上的c
运算符对集合<
进行排序(因此{{1}在字符串上):
<
一个想法可能是使用姓氏和名称连接来计算唯一字符串。因此,如果你有:
比较将在“Smith_George”,“Smith_Garry”和“Smath_George”之间进行,并按照词典顺序命令:
最后,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()等效项优化效率低下的小/普通实现。)