Расположить похожие объекты в массиве рядом

Рейтинг: 0Ответов: 1Опубликовано: 14.02.2023

Я работаю с большими данными, вот упрощённый пример

[
  { a: '0', b: '1' },
  { a: '0', b: '0' },
  { a: '1', b: '1' },
  { a: '2', b: '0' },
  { a: '0', b: '0' },
  { a: '0', b: '1' },
]

Мне нужно расположить похожие по некоторым свойствам записи рядом, например так (порядок не имеет значения)

[
  { a: '0', b: '1' },
  { a: '0', b: '1' },
  { a: '0', b: '0' },
  { a: '0', b: '0' },
  { a: '1', b: '1' },
  { a: '2', b: '0' },
]

С небольшими данным справляется Array.prototype.sort:

data.sort(({ a: a1, b: b1 }, { a: a2, b: b2 }) => a1 === a2 && b1 === b2 ? 0 : 1)

Но вот с большими данными (100к+) это вообще не даёт результата (т.е. записи которые должны быть рядом находятся в разным местах массив)

Оригинальная функция сравнения:

function compare<T>(a: T, b: T, compareKeys: (keyof T)[], dateField: keyof T) {
  const dateFiledA = a[dateField] as unknown as Date
  const dateFiledB = b[dateField] as unknown as Date
  return compareKeys
    .map((c) => a[c] === b[c])
    .concat([
      dateFiledA.getFullYear() === dateFiledB.getFullYear() &&
        dateFiledA.getMonth() === dateFiledB.getMonth() &&
        dateFiledA.getDate() === dateFiledB.getDate(),
    ])
    .every(Boolean) ? 0 : 1
}

Ответы

▲ 1Принят

Скорее всего вам надо правильно прописать фукнцию сравнения. Вот пример для 150к элементов

// Создаем массив в 150к элементов
console.time('add')
const y = [];
for (let i = 0; i <=150000; i++) {
  y.push({
    a: Math.round(Math.random() * 100).toString(),
    b: Math.round(Math.random() * 100).toString()
  })
}
console.timeEnd('add');

// Сортируем
console.time('go');
function microSort(c,d) {
  if (c > d) return 1;
  if (c < d) return -1;
  return 0
}

y.sort((q,w) => {
  if (q.a === w.a) {
    return microSort(q.b, w.b);
  }
  return microSort(q.a, w.a)
})

console.timeEnd('go')

console.log(y.slice(0, 10)); // Первые 10 записей
console.log(y.slice(-10)); // Последние 10 записей

Так же при сравнении надо учитывать тип данных при сравнении. Если есть вложенные объекты, их сортировку придется прописывать отдельно