What's the idiomatic way to detect sequences of x times the same object (or an object with a specific matching parameter) in an OrderedCollection or Array?
E.g. does the Array contain 10 times the number 5 in a row?
I like Uko's answer and would like to provide a different solution which addresses the "matching parameter" part of your question. In SequenceableCollection
define:
contains: m consecutiveElementsSatisfying: block
| n i |
self isEmpty ifTrue: [^m = 0].
n := self size - m + 1.
i := 1.
[i <= n] whileTrue: [| j |
(block value: (self at: i)) ifTrue: [
j := 2.
[j <= m and: [block value: (self at: i + j - 1)]]
whileTrue: [j := j + 1].
j > m ifTrue: [^true]].
i := i + 1].
^false
Now, for example the two following expressions would evaluate to true
#(2 1 1 1 2) contains: 3 consecutiveElementsSatisfying: [:e | e = 1]
#(2 1 0 1 2) contains: 3 consecutiveElementsSatisfying: [:e | e squared = e]
Note: If you want the startingAt: n
version of this method just initialize i := n
instead of i := 1
just before the main loop.
EDIT:
And, of course, we can complete the protocol with the following method in SequenceableCollection
:
contains: m consecutiveTimes: anObject
^self contains: m consecutiveElementsSatisfying: [:e | e = anObject]
And the example:
#(2 1 1 1 2) contains: 3 consecutiveTimes: 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With