Получение последовательности повторяющихся объектов так же просто, как:
({ 1. 1. 2. 2. 2. 5. 5. 3. 9. 9. 9. 9. } as: RunArray) runs
=> #(2 3 2 1 4)
Если вы хотите, чтобы проверить, есть ли пробег, удовлетворяющий специфические ограничения, вы можете сделать что-то вроде следующего:
meetsConstraint := false.
({ 1. 1. 2. 2. 2. 5. 5. 3. 9. 9. 9. 9. } as: RunArray) runsAndValuesDo: [:run :value |
meetsConstraint := (value = 9 and: [run > 3])].
Если вы хотите проверить определенное свойство объекта, а не объект равенства , вы можете легко создать RunArray
этого свойства, сделав collect:
на нем.
Так обобщенное решение будет выглядеть примерно так:
SequenceableCollection >> containsRunOf: anElement withAtLeast: nElements
(self as: RunArray) runsAndValuesDo: [:run :value |
(value = anElement and: [run >= nElements]) ifTrue: [^ true]].
^false
А потом:
({ 'aa'. 'bb'. 'c'. 'ddd'. } collect: [:each | each size])
containsRunOf: 2 withAtLeast: 3
=> false
Ницца. Я бы предложил селектор '#contains: runningOf:', как в '# (2 1 1 1 2), содержит: 3 runOf: 1'. –
@LeandroCaniglia Я еще не очень доволен именем. Однако 'contains: runsOf:' также не будет в точку, так как один «запуск» действительно относится ко всему блоку равных объектов. Поэтому 'runningOf:' будет подразумевать тестирование для нескольких запусков, в то время как мы фактически проверяем один пробег размера 'x'. Может быть, что-то лучше придет мне на ум ... – Leo
Понял. Тогда я думаю, что буду придерживаться 'contains: n последовательныхTimes: anObject', как это было предложено в моем ответе. –