Алгоритм автоматического добавления уникального идентификатора к повторяющимся заголовкам

StackOverflow https://stackoverflow.com/questions/1425159

  •  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 и показываю его пользователю вместе с текстом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top