从OrderedCollection中选择以下项目的最佳方式是什么:

Hel*_*lbo 4 smalltalk pharo

给定像这样的OrderedCollection:

noise1
noise2
noise3
signal1
signal1
signal1
signal1
randomButInteresting
noise4
noise5
Run Code Online (Sandbox Code Playgroud)

我想选择一个新的OrderedCollection所有对象"signal1"和这一系列"signal1"之后的对象,"randomButInteresting".(每个Collection只会发生一次同一个信号.)

这样做最优雅的方法是什么?

Mek*_*nik 5

直接的方法是这样的

| data result lastWasSignal |

data := #( #noise1 #noise2 #noise3 #signal1 #signal1 #signal1 #signal1 #randomButInteresting #noise4 #noise5 ).

lastWasSignal := false.
result := data select: [ :value |
    | isElementAppropriate |
    isElementAppropriate := value = #signal1 or: [ lastWasSignal ].
    lastWasSignal := value = #signal1.
    isElementAppropriate
].

result
Run Code Online (Sandbox Code Playgroud)

这是O(n).更聪明的是使用二进制搜索找到信号组的边界,其发生一次.


Dam*_*sou 3

将 Lukas 版本与 PetitParser 一起使用,但保留结果中的所有“signal1”:

" the parser that accepts the symbol #signal1 "
signal := PPPredicateObjectParser expect: #signal1.

" the parser that accepts many symbols #signal1 followed by something else "
pattern := signal plus , signal negate.

data := #(noise1 noise2 noise3 signal1 signal1 signal1 signal1 randomButInteresting noise4 noise5).

pattern flatten matchesSkipIn: data           -> an OrderedCollection(#(#signal1 #signal1 #signal1 #signal1 #randomButInteresting))
Run Code Online (Sandbox Code Playgroud)