Divide in equal parts c#

Asked

Viewed 557 times

2

I have a class called customer, a call returns, and another call technicians.

in a certain month period, I create returns for these customers.

after creating the returns, I want to split for the technicians I select.

for example. I have 100 clients, so I will generate 100 returns. then I go there and select 4 technicians.

on my controller, I am receiving an array of technicians int[] IdTecnico

so I go to the bank and I look for the returns generated

var retorno = db.retornoDb.Tolist()

how do I make the distribution?

2 answers

5


If you want to divide a vector X for Xn items, and store in a vector where t = Xn / l(t), assuming that l be the item count in t, and then you can go through them and modulating your index for each one:

    int[] x = new int[] {1, 2, 3, 4, 5, 6, 7, 8}; // <~~~ var retorno = db.retornoDb.Tolist()
    int[] t = new int[] {500, 501, 502, 503};   // <~~~ int[] IdTecnico
    int xn = t.Length;

    Dictionary<int, List<int>> tecnicosDivididos = new Dictionary<int, List<int>>();

    // inicializa os itens no dicionario
    foreach(int T in t) {
        tecnicosDivididos.Add(T, new List<int>());
    }

    for(int i = 0; i < x.Length; i++) {
        int I = i % xn;
        int name = t[I];
        (tecnicosDivididos[name] as List<int>).Add(x[i]);
    }

    foreach(KeyValuePair<int, List<int>> item in tecnicosDivididos) {
        Console.WriteLine("{0} => {1}", item.Key, string.Join(", ", item.Value));
    }

See working on .NET Fiddle.

In this way, Xn will always be the count of technicians present in t. The values are stored in a string, List<int>, but in your case, you can pass to Tecnicos, List<retorno>. You only need to inform a way to find the technicians by a key, either by name or by another single variable per item (in your case you use the ID, and implemented in the example the use of the ID).

You should probably change the type of x because he is a int[] and become a retorno[], but this is not necessary if you iterate the indexes of these returns. To generate this index vector, you could use the Enumerable.Range(0, retorno.Length), and then associate each index to each item in the retorno[].

I advise doing this and then pass the notation to Tecnicos, thus, it will not break the algorithm. If you search for key by type Tecnicos, the reference will make the key not exist, and soon will not have the expected result.

Note: the enumeration of returns by technician is not directly sequential, but modular. In fact, there will be no repeated items per technician, and the division will be equal if both are even. If the item count in X is odd, a technician will have an extra item. If the item count in T is odd, a technician will be missing an item.

3

You can create a generic distribution method:

public static class Extensoes {
    public static Dictionary<TU, List<T>> Distribuir<T, TU>
        (this IEnumerable<TU> membros, IEnumerable<T> itens)
    {
        // Dada uma lista de itens a serem distribuídos a uma lista de membros,
        var eItens = itens.ToList();
        var eMembros = membros.ToList();

        // Inicializando o mapa a ser retornado: 
        // Uma coleção vazia de Itens para cada Membro.
        var mapaDeDistribuicao = eMembros
            .ToDictionary(i => i, i => new List<T>());

        // Cache estático do número total de membros
        var numeroDeMembros = eMembros.Count;

        var indiceDeContainer = 0;

        foreach (var item in eItens) // Para cada item da lista de Itens,
        {
            // Adicione-o ao container(Membro) atual;
            mapaDeDistribuicao[eMembros[indiceDeContainer]].Add(item);

            // Selecione o próximo container, ou o primeiro se chegamos ao último.
            indiceDeContainer = (indiceDeContainer + 1) % numeroDeMembros;
        }

        return mapaDeDistribuicao;
    }
}

So you can generate value distribution maps. In the example below,

    var clientes = new List<string>
    {
        "Cliente 1",
        "Cliente 2",
        "Cliente 3",
        "Cliente 4",
        "Cliente 5",
        "Cliente 6",
        "Cliente 7",
        "Cliente 8",
        "Cliente 9",
        "Cliente 10",
        "Cliente 11",
        "Cliente 12",
        "Cliente 13"
    };

    var Tecnicos = new List<string>
    {
        "Tecnico 1",
        "Tecnico 2",
        "Tecnico 3"
    };

    var distribuicao = Tecnicos.Distribuir(clientes);

The dictionary distribuicao will contain a list of customers for each Technician:

Tecnico 1
    Cliente 1
    Cliente 4
    Cliente 7
    Cliente 10
    Cliente 13

Tecnico 2
    Cliente 2
    Cliente 5
    Cliente 8
    Cliente 11

Tecnico 3
    Cliente 3
    Cliente 6
    Cliente 9
    Cliente 12

.NET Fiddle

Browser other questions tagged

You are not signed in. Login or sign up in order to post.