Build possible combinations

Asked

Viewed 460 times

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 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 is ALL possible combinations.

I started doing it, but I couldn’t 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>

2 answers

3

Let’s work on that one Model Categoria, placing 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>
  • And how would I display this on a table, for example?

  • @Diegozanardo Put a piece of View that I improve the answer.

  • Added Gypsy!

  • @Diegozanardo I updated the answer. I don’t quite understand how you want to build this table, but I believe that working the answer code you arrive at the expected result.

  • T giving this error in the method signature, "cannot be an iterator block because List<string>' is not an iterator interface type"

  • @Diegozanardo It was bad! Truth. List cannot be returned by yield. Look now.

  • Now you have another rsrsrs error, Categoriaproxima, it is a category and not a category list... so you are giving error in the option.

  • I tried instead to receive a list of categories, receive only one category, but without success!

  • @Diegozanardo I wrote this code without a proper test. I updated it. Note that I have now done two functions with polymorphism so that the call makes sense.

Show 4 more comments

1

Another way to generate this arrangement would be by using the 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>

The way I see it, you wouldn’t need the properties Ultima, Proxima, etc. if generating the separate arrangement.

  • But there are options that point to different categories. For example in category A the wrinkles option can point to category C and the other options in category A point to category B

Browser other questions tagged

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