【问题标题】:Removing duplicate array elements with order preserved删除保留顺序的重复数组元素
【发布时间】:2017-04-20 10:30:40
【问题描述】:

是否有一种标准方法可以删除数组中的重复条目,但保留顺序?

例如

#(c a b a a b) withoutDuplicates "-> #(c a b)"

我曾经使用removeDuplicates,但显然这是Roassal添加的扩展方法(所以我不能总是使用它)

手写,最好的解决方案(我有)是

a := #(c a b a a b).
d := OrderedDictionary new.
a do: [ :each | d at: each put: true ].
d keys. "-> #(c a b)"

但是有标准的方法吗?

【问题讨论】:

    标签: collections smalltalk pharo


    【解决方案1】:

    与您的相同,但要输入的文本更短,而不是性能。

    (#(c a f b c a d c a e f f) collect: [ :e | e -> true ]) asOrderedDictionary keys
    

    【讨论】:

    • (#(a b c c b d) collect: [:e | e -> true] into: OrderedDictionary new) keys 保存一个临时集合。
    【解决方案2】:

    您的解决方案对我来说非常好。这是另一个:

    withoutDuplicates
      | visited |
      visited := Set new.
      ^self select: [:element | 
        (visited includes: element) not
          ifTrue: [visited add: element];
          yourself]
    

    这个更详细,但使用(仅)一个额外的集合:visited 集合。另一方面,OrderedDictionary 有两个内部集合:Dictionary 和序列orderedKeys。如果您不关心空间,我建议您使用您的解决方案。

    顺便说一句,我想说#yourself 在这里的使用有点不寻常。它遵循模式:

    ^boolean ifTrue: [self doThis]; yourself
    

    booleantrue 并且在任何一种情况下都以boolean 回答时,会产生副作用(self doThis)。大多数人会这样写:

    boolean ifTrue: [self doThis].
    ^boolean
    

    但这需要添加一个临时块,因为在我们的例子中boolean 指的是表达式(visited includes: element) not,我们不应该重复。


    或者...

    ...您可以借此机会在 Pharo 中实现 OrderedSet...


    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 1970-01-01
      • 2017-11-23
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多