Алгоритм автоматического добавления уникального идентификатора к повторяющимся заголовкам
-
07-07-2019 - |
Вопрос
У меня есть пользователь, который вводит фрагмент данных в мою базу данных и называет его "Заголовок виджета".Если он вызовет другой элемент "Заголовок виджета", и еще один, и еще один, когда он увидит их в своем списке виджетов, я бы хотел показать их такими:
- Какой-то Предмет
- Заголовок виджета
- Какой-то Другой Предмет
- Заголовок виджета 2
- Заголовок виджета 3
- Еще Один Предмет
- Заголовок виджета 4
Где каждое повторяющееся вхождение имеет свой собственный добавленный увеличивающийся идентификатор.
Сделаете ли вы это на пути к базе данных или при отображении выходных данных для списка?
Могу я получить алгоритм?
Решение 2
Я просто настроил это на PHP для использования при выводе, и, кажется, это работает хорошо.Вы бы сделали что-нибудь по-другому?
$my_titles_array = array('Some Title',
'Widget Name',
'Widget Name',
'Some Other Title',
'Widget Name',
'Yet Another Title',
'Widget Name'
);
$counted_values_array = array_count_values($my_titles_array);
foreach ($my_titles_array as $title)
{
if($counted_values_array[$title] > 1)
{
$matches_array = array_keys($my_titles_array, $title);
$i=1;
foreach($matches_array as $match)
{
if($i != 1)
{
$my_titles_array[$match] = $title. ' '. $i;
}
$i++;
}
}
}
echo highlight_string(print_r($my_titles_array,true),true);
Другие советы
Хм...попробуйте что-то подобное перед сохранением:
SELECT TOP 1 name FROM widgets WHERE name=@newname OR name LIKE (@newname + ' [0-9]' ORDER BY name DESC
Это даст вам "последнее использованное" имя.
- Если результат равен нулю, коллизии нет
- Если результат совпадает с результатом @newname, добавьте "2".
- Если результатом будет что-то другое, уберите @newname и пробел спереди, преобразуйте в целое число и увеличьте.
Конечно, это распространяется только на 9 дубликатов, или в общей сложности на 10 экземпляров данного имени.Чтобы использовать этот подход для большего, вам нужно будет всегда используйте двузначный суффикс (02, 03 и т.д.) И измените предложение LIKE на match.
(Вы не указали СУБД, так что это написано для Microsoft SQL Server, но синтаксис IIRC с подобными подстановочными знаками похож на другие.)
declare @name nvarchar(40) declare @suffix int declare @currentName nvarchar(50) set @name = 'My Document' set @suffix = 1 set @currentName = @name while exists (select 1 from [table] where [name] = @currentName) begin set @currentName = @name + ' ' + cast(@suffix as nvarchar(10)) set @suffix = @suffix + 1 end
@name в конечном итоге будет "Мой документ 142" (если есть 141 другая копия).Обратите внимание, что если вы удалите копию посередине (скажем, копию 76), следующая копия "заполнит" эту дыру и будет называться "Мой документ 76".
Это T-SQL.
Я просто использую последовательный PK и показываю его пользователю вместе с текстом.