На самом деле этот вопрос - куча проблем, связанных с вашей моделью данных. Вы должны начать распутывать их, по одному. Более естественные, интуитивно понятные решения будут выпадать, если вы попытаетесь упростить каждую часть головоломки.
Проблема 1: Вы не можете зависеть от порядка БД
Ваше описание сортировки ваших данных не ясно.
- Самая большая потенциальная проблема заключается в том, что вы не указываете явную сортировку в своей базе данных через
ORDER BY
предложение. Если вы не потому, что это кажется слишком дорогим, ваша программа имеет ошибку . Базы данных могут возвращать результаты в любом порядке, если вы их не указали; вы не можете полагаться на то, что данные будут возвращаться в порядке совпадения только потому, что вы выполнили запрос несколько раз, и он выглядит так. Порядок может измениться, потому что строки переставляются на диске, или некоторые удаляются, а новые занимают их место, или добавляется индекс. Вы должны указать какой-то ORDER BY
пункт. Скорость бесполезна без правильности.
- Также не ясно, что вы подразумеваете под порядком вставки. Если вы говорите о самой базе данных, у вас должен быть столбец, который фактически отслеживает это, и он должен быть включен в ваше
ORDER BY
предложение. В противном случае у вас есть ошибки. Если такого столбца еще не существует, вам нужно добавить его. Типичными параметрами для таких столбцов могут быть столбец с меткой времени вставки или автоинкрементный ключ. Ключ автоинкремента более надежен.
Проблема 2: Эффективная сортировка в памяти
После того, как вы убедитесь , что он гарантированно будет возврата данных в порядке , вы ожидаете, вы можете использовать этот факт , чтобы сделать в памяти сортирует гораздо более эффективным. Просто добавьте столбец row_number()
илиdense_rank()
(или эквивалент вашей базы данных) в набор результатов запроса. Теперь у каждой строки есть индекс , который даст вам прямое указание того, каким должен быть порядок, и вы можете сортировать его в памяти тривиально. Просто убедитесь, что вы дали индексу осмысленное имя (например sortedBySomethingIndex
).
Виола. Теперь вам больше не нужно зависеть от порядка набора результатов базы данных.
Проблема 3: Вам даже нужно выполнить эту обработку в коде?
SQL на самом деле действительно мощный. Это удивительный декларативный язык, который позволяет вам выполнять множество преобразований и агрегаций в ваших данных. Большинство БД в настоящее время даже поддерживают операции с несколькими строками. Они называются оконными или аналитическими функциями:
Тебе даже нужно вытащить свои данные в память, как это? Или вы могли бы выполнить всю работу в запросе SQL с помощью оконных функций? Если вы можете сделать всю (или, может быть, даже значительную часть) работы в БД, это просто фантастика! Ваша проблема с кодом исчезнет (или станет намного проще)!
Проблема 4: Вы делаете что к этому data
?
Предполагая, что вы не можете сделать все это в БД, позвольте мне сделать это прямо. Вы берете данные как карту (которая основана на вещах, по которым вы не хотите сортировать), затем вы перебираете их в порядке вставки и модифицируете карту на месте, заменяя значение некоторых ключей и добавляя новые?
Извините, но какого чёрта?
Абоненты не должны беспокоиться обо всем этом . Созданная вами система чрезвычайно хрупка. Требуется всего одна глупая ошибка (возможно, даже сделанная вами, как мы все сделали), чтобы сделать одно маленькое неправильное изменение, и все это рухнет, как колода карт.
Вот, возможно, лучшая идея:
- Есть ваша функция принимает
List
.
- Есть несколько способов справиться с проблемой заказа.
- Apply Fail Fast. Выдает ошибку, если список не в том порядке, который требуется для функции. (Примечание. Вы можете использовать индекс сортировки из Задачи 2, чтобы узнать, так ли это.)
- Создайте отсортированную копию самостоятельно (снова используя индекс из задачи 2).
- Придумайте способ построения самой карты по порядку.
- Создайте карту, которая вам нужна, внутри функции, чтобы вызывающий не заботился об этом.
- Теперь итерируйте все, что у вас есть в порядке представления, и делайте то, что вам нужно.
- Вернуть карту или преобразовать ее в соответствующее возвращаемое значение
Возможным вариантом может быть создание отсортированного представления, а затем создание карты ключа к индексу . Это позволит вам изменить вашу отсортированную копию на месте, без случайного создания дубликатов.
Или, может быть, в этом есть больше смысла: избавиться от data
параметра и заставить processData
фактически извлекать его собственные данные. Затем вы можете задокументировать, что вы делаете это, потому что у него очень специфические требования к способу извлечения данных. Другими словами, сделайте функцию владельцем всего процесса, а не только его части; взаимозависимости слишком сильны, чтобы разбить логику на более мелкие куски. (Измените имя функции в процессе.)
Может быть, это не сработает для вашей ситуации. Я не знаю без полной детализации проблемы. Но я знаю хрупкий и запутанный дизайн, когда слышу его.
Резюме
Я думаю, что проблема здесь заключается в том, что дьявол кроется в деталях. Когда я начинаю сталкиваться с подобными проблемами, обычно это происходит из-за того, что у меня неправильное представление моих данных для проблемы, которую я пытаюсь реально решить. Лучшее решение - найти лучшее представление , и тогда моя проблема станет простой (возможно, не простой, но прямой) для решения.
Найдите кого-то, кто получает эту точку зрения: ваша задача сводить вашу проблему к набору простых, простых. Затем вы можете создать надежный, интуитивно понятный код. Поговори с ними. Хороший код и хороший дизайн заставляют вас думать, что любой идиот мог придумать их, потому что они просты и понятны. Может быть, есть старший разработчик, у которого есть такое мышление, с которым вы можете поговорить.