Assemble possible combinations

0

I have the following classes:

public class Categoria
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public bool Primeiro { get; set; }
}

public class Opcao
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public virtual Categoria CategoriaProxima { get; set; }
    public virtual Categoria Categoria { get; set; }
    public bool Ultima { get; set; }
}

Data example:

Categoria                           Opcao

Escolha o que deseja tratar         Rugas
Escolha o que deseja tratar         Manchas
Escolha o que deseja tratar         Olheiras
Escolha o que deseja tratar         Fotoproteção
Escolha o que deseja tratar         Flacidez

Selecione seu tipo de pele          Pele Normal
Selecione seu tipo de pele          Pele Oleosa
Selecione seu tipo de pele          Pele Seca
Selecione seu tipo de pele          Pele Extra Seca

Selecione seu tipo de ruga          Rugas Finas
Selecione seu tipo de ruga          Rugas Médias
Selecione seu tipo de ruga          Rugas Profundas

Selecione seu fototipo              Fototipo 1
Selecione seu fototipo              Fototipo 2
Selecione seu fototipo              Fototipo 3
Selecione seu fototipo              Fototipo 4

I would like to get the following result:

Rugas - Pele Normal - Rugas Finas - Fototipo 1
Rugas - Pele Normal - Rugas Finas - Fototipo 2
Rugas - Pele Normal - Rugas Finas - Fototipo 3
Rugas - Pele Normal - Rugas Finas - Fototipo 4

Rugas - Pele Normal - Rugas Médias - Fototipo 1
Rugas - Pele Normal - Rugas Médias - Fototipo 2
Rugas - Pele Normal - Rugas Médias - Fototipo 3
Rugas - Pele Normal - Rugas Médias - Fototipo 4
(...)

That means ALL possible combinations.

I started to do, but I could not evolve:

foreach (var opcao in opcoes.Where(x => x.Categoria.Primeiro == true))
{
    // Pular Linha
    opcao.Nome //Exibir Opcao
    while(opcao.Ultima==false){
        // Pular Linha
    }


    proximaCategoria = opcao.CategoriaProxima;
    foreach(var proximaOpcao in opcoes.Where(x=>x.CategoriaProxima.Id == proximaCategoria.Id)){

    }

[VIEW]

@model IEnumerable<Dominio.Categoria>
@{
    var opcoes = ViewData["Opcoes"] as IEnumerable<Dominio.Opcao>;
}
<table>
    <thead>
       <tr>
        @foreach (var categoria in Model)
        {
            <th>
               @categoria.Nome
            </th>
         }
         </tr>
      </thead>
    <tbody>
        @foreach (var opcao in opcoes.Where(x=>x.Categoria.Primeiro == true)) {
            (...)
        }  
     </tbody>
</table>
    
asked by anonymous 14.10.2014 / 20:14

2 answers

3

Let's give one a hand at this Model Categoria , putting the inverse property of options:

public class Categoria
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public bool Primeiro { get; set; }

    public virtual ICollection<Opcao> Opcoes { get; set; }
}

I would do two functions, being a recursive:

public IEnumerable<String> MontarListaDeOpcoes(List<Categoria> categorias) 
{
    foreach (var categoria in categorias) 
    {
        foreach (var opcao in categoria.Opcoes) 
        {
            if (!opcao.Ultima)
            {
                yield return opcao.Nome + " - " + MontarListaDeOpcoes(opcao.CategoriaProxima);
            } else {
                yield return opcao.Nome;
            }
        }
    }
}

public IEnumerable<String> MontarListaDeOpcoes(Categoria categoria) 
{
    foreach (var opcao in categoria.Opcoes) 
    {
        if (!opcao.Ultima)
        {
            yield return opcao.Nome + " - " + MontarListaDeOpcoes(opcao.CategoriaProxima);
        } else {
            yield return opcao.Nome;
        }
    }
}

View

@model IEnumerable<String>

<table>
    <thead>
       <tr>
            <th>
               Opções
            </th>
         </tr>
      </thead>
    <tbody>
        @foreach (var opcao in Model) 
        {
            <tr>
                <th>
                    @opcao
                </th>
             </tr>
        }  
     </tbody>
</table>
    
14.10.2014 / 21:39
1

Another way to generate this arrangement would be to use SelectMany .

See an implementation:

// Não utilizei objeto criado por você para facilitar o exemplo.
var categoriaA = new[] { "Rugas","Manchas","Olheiras","Fotoproteção","Flacidez"};
var categoriaB = new[] { "Pele Normal","Pele Oleosa","Pele Seca","Pele Extra Seca"};
var categoriaC = new[] { "Rugas Finas","Rugas Médias","Rugas Profundas"};
var categoriaD = new[] { "Fototipo 1","Fototipo 2","Fototipo 3","Fototipo 4"};

// Escolhe todas as categorias, onde a ordem importa.
var arranjos =
    from a in categoriaA
    from b in categoriaB
    from c in categoriaC
    from d in categoriaD
    select new { a,b,c,d,Descricao = string.Format("{0} - {1} - {2} - {3}", a,b,c,d) };

ViewData["Opcoes"] = arranjos;

View

<table>
    <thead>
       <tr>
            <th>a</th>
            <th>b</th>
            <th>c</th>
            <th>d</th>
            <th>Descrição</th>
         </tr>
      </thead>
    <tbody>
        @foreach (var item in ViewData["Opcoes"]) 
        {
            <tr>
                <td>@item.a</td>
                <td>@item.b</td>
                <td>@item.c</td>
                <td>@item.d</td>
                <td>@item.Descricao</td>
             </tr>
        }  
     </tbody>
</table>

In my opinion, you would not need the Ultima , Proxima , and so on properties. if you generate the separate arrangement.

    
15.10.2014 / 00:59