Tuve que escribir algo en MVC para un control de anuncios ponderado que no mostraba el mismo anuncio dos veces seguidas si era posible y en mi prisa terminé con un código terrible que podría servir como inspiración para usted .
Estoy seguro de que hay muchas formas mejores de hacer esto (y ya sé casos en que esto permite que los duplicados pasen cuando no debería) pero durante el corto período de tiempo que pasé allí hice el trabajo.
public List<Ad> GetRandomWeightedAds()
{
/* Generate random order list of ads with duplicates for ViewsPerRotation */
List<Ad> returnList = GetAllAds().SelectMany(s => Enumerable.Repeat(s, s.ViewsPerRotation)).OrderBy(s => Guid.NewGuid()).ToList();
for (int i = 0; i < returnList.Count - 1; i++) /* Compare all but the last element against subsequent element */
{
if (returnList[i].Id == returnList[i + 1].Id)
{
/* If next to an identical element try and find a new spot for the subsequent element */
for (int j = 0; j < returnList.Count; j++)
{
if (returnList[j].Id != returnList[i].Id /* Don't switch identical element back into same pos*/
&& (j<i || j == 0 || j-1 == i || returnList[i].Id != returnList[j - 1].Id) /* When moving before current 'i', don't move into a place after an identical element */
&& (j<i || j == returnList.Count - 1 || j + 1 == i || returnList[i].Id != returnList[j + 1].Id)) /* When moving before current 'i', don't move into a place before an identical element */
{
returnList[i] = returnList[j];
returnList[j] = returnList[i+1]; /* returnList[i+1] == returnList[i] */
break;
}
}
}
}
return returnList;
}
No veo nada de malo en la pregunta. –
@ [KingNestor]: la redacción es excelente, gracias; ahora es una pregunta general. Tu castillo ahora está hecho de piedra en lugar de arena. –
Nada malo con los castillos de arena, aparte de los niños punk que los patean para arruinar el día de los demás. – ceejayoz