2

I have 3 classes:

public class Disciplina
{
    public int Key { get; set; }
    public string Name { get; set; }
    public string[] Semestr { get; set; }
    public int Time { get; set; }
    public List<int> TimeToAll { get; set; }
    public string Otchetnost { get; set; }
    public int Specialnost { get; set; }
    ...
}

public class Cafedra
{
    public int Key { get; set; }
    public string Name { get; set; }
    public string Facultet { get; set; }
    public string Telefone { get; set; }
    public List<int> Specializations { get; set; }
    ...
}

public class Specialization
{
    public int Key { get; set; }
    public string Name { get; set; }
    public string SpecialName { get; set; }
    public string FormaObuch { get; set; }
    public string[] DisplinsID { get; set; }
    ...
}

I need to choose all Disciplina of chosen cafedra. I created by many foreach but I need it with linq.

I tried, but one Cafedra can have a lot of Specialization, and the Specialization can have a lot of Disiplins and I do not know how it can be chosen in a LINQ?

My method

private static void DiscipliniCafedri()
{
    Console.WriteLine("Выберите кафедру:");
    for (int i = 0; i < Cafedras.Count; i++)
    {
        Console.WriteLine(i + 1 + " " + Cafedras[i].ToString());
    }
    int ID = Convert.ToInt32(Console.ReadLine());

    List<Specialization> spesc = new List<Specialization>();
    Console.Clear();
    Console.WriteLine("Дисциплины выбранной кафедры:");

    foreach (int s in Cafedras[ID - 1].Specializations)
    {
        spesc.Add(Specializations[s - 1]);
    }

    foreach (Specialization s in spesc)
    {
        foreach (string d in s.DisplinsID)
        {
            Console.WriteLine(Disciplinas[Convert.ToInt32(d) - 1].Name);
        }
    }
}
Alex Sikilinda
  • 2,928
  • 18
  • 34
SuxoiKorm
  • 159
  • 2
  • 11
  • Selectmany eg cagedra.selectmany(c=>c.specilation ) – Sentinel May 20 '18 at 13:26
  • Possible duplicate of [Linq list of lists to single list](https://stackoverflow.com/questions/1145558/linq-list-of-lists-to-single-list) – arekzyla May 20 '18 at 13:27
  • 1
    In English, "кафедра" would be "department", and "дисциплина" is usually translated as "subject" in the context of modeling a university. – Sergey Kalinichenko May 20 '18 at 13:32

2 Answers2

2

Converting nested loops does not require a join - you can do a sequence of Select calls instead:

var res = Cafedras[ID - 1]
    .Specializations
    .Select(s => Specializations[s - 1])
    .SelectMany(s => Disciplinas[Convert.ToInt32(s.DisplinsID) - 1].Name)
    .ToList();

Above,

  • First Select represents the first loop that creates specs
  • Second SelectMany represents the two nested loops.

This produces List<string> in the res, with subject names that could be printed.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • DisplinsID is to array. I made like Aomine with one more select. Thanks! var resultSet = Cafedras[ID - 1].Specializations .Select(s => Specializations[s - 1]) .SelectMany(s => s.DisplinsID).Select(s => Disciplinas[Convert.ToInt32(s) - 1]); – SuxoiKorm May 20 '18 at 13:54
1

The LINQ equivalent would be:

var resultSet = Cafedras[ID - 1].Specializations
                .Select(s => Specializations[s - 1])
                .SelectMany(s => s.DisplinsID);

foreach(var d in resultSet)
     Console.WriteLine(Disciplinas[Convert.ToInt32(d) - 1].Name);
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126