максимально легкий способ поиска совпадений из объекта JS
Задача в том чтоб постоянно искать совпадения в объекте (не массиве) минимально нагружая сервер.
Есть объект в который в любой момент может упасть новая запись и мне надо проверить ее на совпадения с другими записями и выдать некий результат (удалив эти записи из объекта).
подобным методом я сейчас перебираю и ищу совпадения:
let array: any = Object.keys(this.list) || 0;
if (array?.length <= 1) {
this.isSearching = false;
} else if (array.length >= 2) {
this.isSearching = true;
array.forEach((first: any) => {
let firstUser = this.list[first];
array.some((second: any) => {
let secondUser = this.list[second];
if(firstUser.age === secondUser.age && firstUser.city === secondUser.city) {
/* Удаляем пользователей и выдаем результат */
return true
} else {
return false;
}
}
})
/* Запускаем функцию рекурсивно через 250ms*/
}
Но это черновой вариант лишь бы работало... вот сижу и думаю как оптимизировать этот код так чтоб быстрее работало (проблем нет пока что но под нагрузкой кто знает...) и меньше нагружало ЦП ибо сервер слабенький а это вообще второстепенная задача.
Если рекурсивный запуск я не ставлю через таймер то сервер захлебуется и падает.
Рассмотрю любые предложения и буду очень благодарен за помощь!
Ответы (1 шт):
Как один из возможных сценариев можно делать проверку сразу при добавлени.
Можно воспользоваться буферным объектом и делать проверку при достижении какого-то условия либо таймаута с момента добавления первого ключа в объект. Почему первого:
- потому что если ключей нет то ничего делать не стоит
- никогда не ясно сколько может быть ключей
- это гарантирует наступление слияния даже в минимальном случае
Ну и конечно использование хэшей может сократить время на сравнение (время будет тратится только на создание хэша)
const base = {
'hash01': {
age: 21,
city: "New York"
},
'hash02': {
age: 18,
city: "Cape Town"
}
}
console.log('база', base)
// можно запускать сразу при добавлениии
const addObject = (hash, age, city) => {
const filtered = Object.entries(base)
.filter(([key, value]) => age === value.age && city === value.city);
if (filtered.length){
filtered.forEach(e => {
delete base[e[0]]
})
return true;
}
base[hash] = {age, city}
return false
}
console.log('простое добавление:',
{hash: 'hash03', age: 21, city: 'New York'},
addObject('hash03', 21, 'New York'))
//либо добавлять во временный объект
const temp = {}
const addTemp = (hash, age, city) => {
temp[hash] = {age, city}
// через какое-то время или при наличии
// определенного числа записей можно запустить
// очистку
if (Object.entries(temp).length === 3){
console.log('превышен лимит буфера')
Object.entries(temp).forEach(e => {
const [hash, {age, city}] = e;
console.log('слияние', {hash, age, city})
addObject(hash, age, city);
delete temp[hash];
})
}
//просмотреть общий результат можно так
console.log('общая база:', {...base, ...temp})
}
addTemp('hash03', 21, 'New York')
addTemp('hash04', 21, 'New York')
addTemp('hash05', 21, 'New York')
addTemp('hash06', 21, 'New York')
addTemp('hash07', 21, 'New York')
addTemp('hash08', 21, 'New York')