максимально легкий способ поиска совпадений из объекта 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 шт):

Автор решения: Daniil Loban

Как один из возможных сценариев можно делать проверку сразу при добавлени.

Можно воспользоваться буферным объектом и делать проверку при достижении какого-то условия либо таймаута с момента добавления первого ключа в объект. Почему первого:

  • потому что если ключей нет то ничего делать не стоит
  • никогда не ясно сколько может быть ключей
  • это гарантирует наступление слияния даже в минимальном случае

Ну и конечно использование хэшей может сократить время на сравнение (время будет тратится только на создание хэша)

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')

→ Ссылка