Generate unique color for each result

5

So .. I have a system of comments anonymously in a project of mine that in place of the avatar it puts the abbreviation of the name of the person, for example:

Vinicius Eduardo -> VE

and I want to create a system or function that generates a unique COR for each abbreviation, so the user can be identified more easily.

Summarizing everything, I have an array containing 24 colors in "#VLVLVL" format and for each abbreviation it will give a unique color, for example VE - > #cccccc ED - > # 000000 and if the VE comment again the color of it repeats itself as #cccccc

    
asked by anonymous 19.06.2014 / 03:28

2 answers

7

Considering an array of colors like this:

$cores = array('#000', '#333', '#666', '#999'); // do tamanho que você precisar

I would create a second array, associative, where you save the colors for each user. It starts empty:

$coresPorUsuario = array();

And the idea is that it will contain the colors of the users as they emerge. For example, array('VE' => '#000', 'ED' => '#333') .

To control everything, use a function. It receives the initials of the user and returns the corresponding color. If the user already exists in $coresPorUsuario , get the color that is there. If it does not exist, it takes the next available color, associates it with the user, and returns that color. You will also need a variable to control the next available color.

$proxima = 0;    
function corUsuario($usuario) {

    global $cores;
    global $coresPorUsuario;
    global $proxima;

    // Usuário ainda não existe na array
    if(empty($coresPorUsuario[$usuario])) {
        // Guarda a cor do usuário e avança para a próxima cor disponível
        $coresPorUsuario[$usuario] = $cores[$proxima++];

        // Se passou da quantidade de cores disponíveis, começa novamente da primeira
        $proxima = $proxima == count($cores) ? 0 : $proxima;
    }

    // Retorna a cor do usuário
    return $coresPorUsuario[$usuario];
}
  

WARNING: The above example uses global variables because it is a short path as an example. You probably want to implement this function as a method of a class. In this case, use instance properties instead of global variables.

Testing:

echo corUsuario('AA') . "\n"; // #000
echo corUsuario('AB') . "\n"; // #333
echo corUsuario('AC') . "\n"; // #666
echo corUsuario('AA') . "\n"; // #000
echo corUsuario('AD') . "\n"; // #999
echo corUsuario('AE') . "\n"; // #000

Demonstration

    
19.06.2014 / 05:36
4

You can create an array for the already used colors and another one for the colors of each user.

I could use a shorter and more practical solution, (and that alias used less CPU ..) but I wanted the colors to be random .. but since the users (sorted by ID) are already random enough, I think the solution of the best bfavaretto. Although I find his solution more practical and lightweight, I will keep my case still have some use ...

I made a simple "illustration".

<?php
// Array para as cores de cada usuário.
# "NomeDeUsuario" => "COR HEX";
$usersColors = array();

// Array para as cores disponiveis [usei cores aleatorias]
$avaliableColors = array(
    0 => "#ececea",
    1 => "#efefef",
    2 => "#abcdef"
);

// Primeiro pegamos os usuários, eles são a parte importantes
$users = array(
    'banana123',
    'SouEUmesmo',
    'kitKat159',
);

// Se tiver mais usuários do que cores, abortar execução
if ( count($users) > count($avaliableColors) ) {
    die("ERRO: existem mais usuários do que cores.");
}

// Vamos criar uma array que guarda as cores ja usadas, pra não repeti-las
$alreadyUsed = array();
$userCount = count($users);
$colorCount = count($avaliableColors);

// Definindo uma cor aleatoria para cada um
for ($i=0;$i<$userCount;++$i) {
    // Numero aleatorio representando uma das cores.
    $max = $colorCount-1;
    $numeroAleatorio = rand(0, $max);

    if (in_array($numeroAleatorio, $alreadyUsed)) {
        // Se o numero ja tiver sido usado, ficar até encontrar um não utilizado
        $numeroNaoUsadoEncontrado = false;

        while ($numeroNaoUsadoEncontrado != true) {
            $numeroAleatorio = rand(0, $max);

            // Se o numero não tiver sido utilziado aidna
            if (!in_array($numeroAleatorio, $alreadyUsed)) {
                // Sair do loop de tentativas
                $numeroNaoUsadoEncontrado = true;

                // Colocar esse numero como já usado.
                $alreadyUsed[] = $numeroAleatorio;
            }
        }
    }
    else {
        // Colocar esse numero como já usado.
        $alreadyUsed[] = $numeroAleatorio;
    }

    // Agora que a cor ja foi escolhida, atribuir ela ao usuário
    $userName = $users[$i];
    $usersColors[$userName] = $avaliableColors[$numeroAleatorio];
}


# DEBUG
echo "<br>";
foreach ($usersColors as $user => $color) {
    echo $user . " -> " . $color . "<br/>\n";
}
    
19.06.2014 / 04:58