Data with repeated 'i's followed by 'i's and/or 't's.
data = ['i','t','t','i','i','t','t','t']
Trying to retrieve the index of the last 't' in the pattern ['i','t','t']:
[2,6] // ['i','t','t','i','i','t','t','t'] # position of the returned 't's
// _______ ^ _______ ^
I'm looking for a non-recursive solution using (pure) functions only, using ramdajs for example.
Tried to use reduce
and transduce
, but unsuccessful sofar.
One approach would be to use R.aperture
to iterate over a 3-element sliding window of the data
list, then tracking the position of any sub-list that equals the pattern ['i', 't', 't']
.
const data = ['i','t','t','i','i','t','t','t']
const isPattern = R.equals(['i', 't', 't'])
const reduceWithIdx = R.addIndex(R.reduce)
const positions = reduceWithIdx((idxs, next, idx) =>
isPattern(next) ? R.append(idx + 2, idxs) : idxs
, [], R.aperture(3, data))
console.log(positions)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>
A point-free version of this approach could look something like the following, though whether this is preferable comes down to a preference of style/readability.
const data = ['i','t','t','i','i','t','t','t']
const isPattern = R.equals(['i', 't', 't'])
const run = R.pipe(
// create sliding window of 3 elements
R.aperture(3),
// zip sliding window with index
R.chain(R.zip, R.compose(R.range(0), R.length)),
// filter matching pattern
R.filter(R.compose(isPattern, R.nth(1))),
// extract index
R.map(R.compose(R.add(2), R.head))
)
console.log(run(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>