2017-02-02 20 views

回答

1

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

在你的情况,假设你有一个surname属性,下面的语句将使用<操作上的每个姓氏排序集合c聚集(等串的<):

c->sortedBy(p | p.surname) 

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

  • 乔治·史密斯
  • 加里·史密斯
  • 乔治Smath

比较会 “Smith_George”, “Smith_Garry” 和 “Smath_George” 并会之间完成有序,继字典顺序,来:

  1. 乔治Smath(SM 一个吨h_George)
  2. 加里史密斯(Smith_G 一个 RRY)
  3. 乔治·史密斯(smith_G Ë萨维尼)

最后,OCL请求将是(假设surnamename作为现有属性):

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

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

+0

在我看来,这个解决方案将不会在所有情况下,我需要一件大事ersal。如果我们有例如两个日期,这个解决方案将是错误的。例如,项目开始的日期和项目完成的日期。我可以在这种情况下使用什么? – DM14

+0

正如我所说,这种解决方案在您的具体情况下使用名称/姓氏是它会使用字典顺序。我不确定,但我不认为OCL sortedBy函数能够执行这两个条件搜索。在其他情况下,应该找到另一个技巧,在您的开始/结束日期示例中,您可以使用结束/开始日期计算每个项目花费的时间,并使用此标准对它们进行排序。否则,以yyy-mm-dd格式翻译日期(带有明显的0显式),带字典顺序的字符串技巧应该起作用。 –

0

OCL sortedBy(lambda)似乎与Java的排序(比较器)有很大不同,显然需要投影对象作为排序的度量。但是,如果投影是自己的,你有不同的Java功能。因此,如果您执行sortedBy(p | p),则排序取决于p的<操作。

为了推动这项工作,未来OCL的Eclipse的OCL原型引入了OclComparable类型有compareTo方法使得能够实现所有的关系操作提供您的自定义类型扩展OclComparable类型。

(A类似OclSummable零()和sum()操作支持收藏::总和()一般;如字符串实现和作为串联)

0

感谢您启发了我。我刚刚提出了http://issues.omg.org/browse/OCL25-213其文本是:

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

然而,sortedBy解决方案并不熟悉,因此对于新手而言如此混乱,并且不适用于需要构建人造复合单键的多键分类。

一种解决方案是,提供一种更常规的迭代器例如排序(P1,P2 |比较表达)允许两键排序:

排序(P1,P2 |让DIFF1 = p1.key1.compareTo (p2.key1)in if diff1 <> 0 diff 1 else p1.key2.compareTo(p2.key2)endif)

但是这样做的可读性差,而且有很多错别字的机会。

备选地sortedBy与元组值度量可能支持多个键为:

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

(元组部分的名称的字母顺序确定优先级)。

(由于sortedBy是声明明确而紧凑,效率低下的小/琐碎的实现可以优化自己的sort()的等价物。)