Вы можете взять счетчик индекса для той же группы и получить значение, если найдено значение с единицей.
Пример 3:
[1, 2, 1, 3, 1, 1, 2, 2, 3] ids
[0, 0, 1, 0, 0, 0, 1, 0, 1] values
0 0 1 0 2 3 1 2 1 indices by group
^ ^ ^ result
function getIndices(ids, values) {
var map = new Map;
return ids.reduce((r, v, i) => {
if (values[i] === 1) r.push(map.get(v) || 0);
map.set(v, (map.get(v) || 0) + 1);
return r;
}, []);
}
// [1, 2, 0]
console.log(...getIndices([1, 1, 1, 2, 2, 2, 3, 3], [0, 1, 0, 0, 0, 1, 1, 0]));
// [1, 1, 3]
console.log(...getIndices([1, 1, 1, 2, 2, 2, 3, 3, 3, 3], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1]));
// [1, 1, 1]
console.log(...getIndices([1, 2, 1, 3, 1, 1, 2, 2, 3], [0, 0, 1, 0, 0, 0, 1, 0, 1]));
Вместо Map
вы можете взять объект в качестве хеш-таблицы для индексации значений.
function getIndices(ids, values) {
var hash = Object.create(null);
return ids.reduce((r, v, i) => {
hash[v] = hash[v] || 0;
if (values[i] === 1) r.push(hash[v]);
hash[v]++;
return r;
}, []);
}
// [1, 2, 0]
console.log(...getIndices([1, 1, 1, 2, 2, 2, 3, 3], [0, 1, 0, 0, 0, 1, 1, 0]));
// [1, 1, 3]
console.log(...getIndices([1, 1, 1, 2, 2, 2, 3, 3, 3, 3], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1]));
// [1, 1, 1]
console.log(...getIndices([1, 2, 1, 3, 1, 1, 2, 2, 3], [0, 0, 1, 0, 0, 0, 1, 0, 1]));