Algoritmo per l'aggiunta automatica di un ID univoco a titoli duplicati
-
07-07-2019 - |
Domanda
Ho un utente che inserisce un dato nel mio database e lo titolo "Widget Title". Se chiama un altro elemento "Titolo widget" e un altro e un altro, quando li vede nella sua lista di widget, vorrei mostrarli in questo modo:
- Alcuni elementi
- Titolo widget
- Qualche altro oggetto
- Titolo Widget 2
- Titolo widget 3
- Yet Another Item
- Titolo del widget 4
Dove ogni ricorrenza duplicata ha il proprio ID incrementale aggiunto.
Lo faresti mentre entri nel database o quando visualizzi l'output per l'elenco?
Posso avere l'algoritmo?
Soluzione 2
L'ho appena montato in PHP per l'uso in output e sembra funzionare bene. Faresti qualcosa di diverso?
$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);
Altri suggerimenti
Hmm ... prova qualcosa del genere prima di salvare:
SELECT TOP 1 name FROM widgets WHERE name=@newname OR name LIKE (@newname + ' [0-9]' ORDER BY name DESC
Questo ti fornirà l'ultimo "quot" usato nome.
- Se il risultato è nullo, non vi è alcuna collisione
- Se il risultato è lo stesso di @newname, aggiungi " 2 "
- Se il risultato è qualcos'altro, tagliare @newname e lo spazio dalla parte anteriore, convertire in un numero intero e incrementare.
Ovviamente, questo ti coprirà solo per 9 duplicati o per un totale di 10 istanze di un determinato nome. Per utilizzare questo approccio per altro, devi sempre utilizzare un suffisso a due cifre (02, 03, ecc.) E modificare la clausola LIKE in modo che corrisponda.
(Non hai specificato un RDBMS, quindi questo è scritto per Microsoft SQL Server, ma IIRC la sintassi jolly LIKE è simile in altri.)
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 finirà per essere " My Document 142 " (se ci sono altre 141 copie). Nota che se elimini una copia nel mezzo (diciamo, copia 76), la copia successiva " compilerà " quel buco ed essere chiamato My Document 76.
Questo è T-SQL.
Uso solo un PK seriale e lo mostro all'utente accanto al testo.