Надо запоминать индекс последнего подходящего элемента, если равен текущему минус один - помещаем текущий элемент в последнюю группу, нет - создаём новую:
const filterAndGroupAdjacent = (data, filterFn) =>
Array.prototype.reduce.call(
data,
(acc, n, i, a) => {
if (filterFn(n, i, a)) {
const len = acc[0].length;
(acc[1] === ~-i ? acc[0][~-len] : (acc[0][len] = [])).push(n);
acc[1] = i;
}
return acc;
},
[ [], null ]
)[0];
Примеры использования:
// достаём нечётные числа
filterAndGroupAdjacent(
[ 1, 7, 3, 2, 3, 4, 4, 9, 5 ],
n => n & 1
) // [ [1,7,3], [3], [9,5] ]
// буквы в верхнем регистре
filterAndGroupAdjacent(
'1_Df+HNU*@qpJM!x',
RegExp.prototype.test.bind(/[A-Z]/)
) // [ ["D"], ["H","N","U"], ["J","M"] ]