You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
10 Hrs
46 Min
37 Seg

Introduciendo datos en un diccionario

18/35
Resources

How to improve the implementation of a dictionary in C#?

When handling complex data in programming, it is crucial to follow good practices to ensure that our code is scalable and efficient. A perfect example is the use of dictionaries to group objects in C#. In this guide, we are going to explore how to improve the implementation of a dictionary that manages schools, courses, students, subjects and assessments. Read on to understand how to optimize your code and avoid common mistakes.

How to structure the dictionary?

First, it is important to keep in mind that our dictionary must allow to store elements within specific categories. In this case, the categories are: school, courses, students, subjects and evaluations. The basic structure starts by establishing keys for each of these groups and initializing empty lists ready to be filled with the corresponding information.

var dictionary = new Dictionary<string, List<object>>();dictionary.Add("school", new List<object>());dictionary.Add("courses", new List<object>());dictionary.Add("students", new List<object>());dictionary.Add("subjects", new List<object>());dictionary.Add("evaluations", new List<object>());

How are foreach cycles handled?

Proper implementation of foreach cycles is vital for traversing lists and adding elements corresponding to each part of the dictionary. A nested cycle is used to iterate through collections and ensure that the correct information is assigned to each list within the dictionary.

  1. Courses: For each course in the school, subjects and students will be added to their respective lists.
  2. Students: A cycle is run for each student, and they are added to the student list.
  3. Evaluations: A list of assessments is obtained for each pupil, and they are added to the list of assessments.
foreach (var course in school.Courses) { foreach (var subject in course.Subjects) { dictionary["subjects"].Add(subject); } }    
 foreach (var student in course.Students) { dictionary["students"].Add(student); foreach (var assessment in student.Assessments) { dictionary["assessments"].Add(assessment); } }} } }

How to avoid mistakes when adding evaluations?

One of the most frequent errors is trying to add the same key to the dictionary more than once. To solve this problem, you should use a temporary list where all evaluations are accumulated before adding them to the dictionary. At the end of the cycle, all evaluations can be added at once using this temporary list, avoiding key duplication errors.

var listTemporalEvaluations = new List<Evaluation>();foreach (var course in school.Courses) { foreach (var student in course.Students) { listTemporalEvaluations.AddRange(student.Evaluations); } } }dictionary["evaluations"] = listTemporalEvaluations.Cast<object>().ToList();

How to avoid duplications within the dictionary?

To prevent the introduction of duplicate data and logical errors, careful management of loop flow and list filling is essential. Implement temporary lists for intermediate collections and make sure that you do not add the same collection to the dictionary for several iterations of the loop.

  1. Temporary lists: Use temporary lists to group subjects and students.
  2. Add at the end: Populate temporary lists and then add them to the dictionary after completing iterations.

By applying these strategies, you will significantly improve the efficiency and robustness of your code. Keep in mind that practice and continuous review are essential for quality software development - keep experimenting and improving your programming skills!

Contributions 24

Questions 0

Sort by:

Want to see more contributions, questions and answers from the community?

Una variante de recorrer el objeto Escuela:

Excelente ver como Juanca Aborda los errores de codigo en tiempo real!!

No es necesario hacer el CAST

public Dictionary<MyKeys, IEnumerable<ObjetoEscuelaBase>> GetOjetosEscuelaDiccionario()
{
    var dic = new Dictionary<MyKeys, IEnumerable<ObjetoEscuelaBase>>();
    
    dic.Add(MyKeys.Escuela, new[] {Escuela});
    dic.Add(MyKeys.Curso, Escuela.Cursos);
    
    var listatmpEva = new List<Evaluacion>();
    var listatmpAl = new List<Alumno>();
    var listatmpAsi = new List<Asignatura>();
    foreach (var curso in Escuela.Cursos)
    {
        listatmpAsi.AddRange(curso.Asignaturas);
        listatmpAl.AddRange(curso.Alumnos);
            
        foreach (var alumno in curso.Alumnos)
        {
            listatmpEva.AddRange(alumno.Evaluaciones); 
        }
    }   
    
    dic.Add(MyKeys.Evaluacion, listatmpEva);
    dic.Add(MyKeys.Asignatura, listatmpAsi);
    dic.Add(MyKeys.Alumno, listatmpAl);
    return dic;
}

Me vuela la cabeza el poder tomar clases con profesos de diferentes partes del mundo, si no fuese por Internet y el gran trabajo de Platzi esto no seria posible! ❤️

se hizo larga la clase buscando los errores pero siempre es bueno ver los casos que se dan.

Está bueno que el profesor se equivoque también, sino siempre idealizamos a la personas y pensamos que nunca lo hacen y que sólo nos equivocamos nosotros, además nos enseña a como debuggear y encontrar los errores, me gustó la clase 😃

En este caso para poder iterar un dictionary lo podremos hacer de la siguiente manera

foreach(var item in myDictionary)
{
foo(item.Key);
bar(item.Value);
}

or

foreach(var item in myDictionary.Keys)
{
foo(item);
}

or
foreach(var item in myDictionary.Values)
{
foo(item);
}

Si no estoy equivocado, podemos añadirle las listas sin tener que hacerle el cast al diccionario, ya que cada objecto hereda de la clase objetoEscuelaBase, por lo tanto son un "objetoEscuelaBase " y al crear listas para añadir los objetos de la escuela estas implementan IEnumerable.
Ej: La escuela se añadio al dictionary porque fue
envuelta en un array sin hacerle cast. Lo mismo se puede hacer con las demas listas

public static Dictionary<ObjectKey, IEnumerable<SchoolBaseObject>> SchoolObjects () {
         var dictionary = new Dictionary<ObjectKey, IEnumerable<SchoolBaseObject>> ();
         List<Evaluation> evaluationsList = new List<Evaluation> ();
         List<Student> studentsList = new List<Student> ();
         List<Subject> subjectsList = new List<Subject> ();

         foreach (var course in School.Courses) {
            studentsList.AddRange (course.Students);
            evaluationsList.AddRange (course.Evaluations);
            subjectsList.AddRange (course.Subjects);
         }

         dictionary.Add (ObjectKey.School, new [] { School });
         dictionary.Add (ObjectKey.Course, School.Courses);
         dictionary.Add (ObjectKey.Student, studentsList);
         dictionary.Add (ObjectKey.Subject, subjectsList);
         dictionary.Add (ObjectKey.Evaluation, evaluationsList);

         return dictionary;
      }

No sé si es intencional (es lo que yo creo) o no, pero me siento como en dora la exploradora, buscando el bug, y me gusta porque te hace ver que no todo en programación es perfecto, like por la clase.

Es buena practica siempre abrir y cerrar las llaves en los bucles, if, etc., aún cuando se vaya a escribir una sola sentencia, por legibilidad y por prevención de errores en futuras modificaciones del código.

Errores por no usar lista temporal xd

Grande, La explicación de diccionarios

Excelente contenido, muy bien demostrado que tenemos problemas y se solucionan con el debug genial

Algo que no me gustó es que el profesor no siempre lee el mensaje de error completo, donde se dice claramente cual es la línea que está generando problemas.

Aporte de como realice la función sin necesidad del Cast

        public Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> GetObjectDictionary()
        {

            Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dictionary = new();
                       
            var evaluaciones = new List<Evaluacion>();
            var asignaturas = new List<Asignatura>();
            var alumnos = new List<Alumno>();

            Escuela.Cursos.ForEach(curso =>
            {
                alumnos.AddRange(curso.Alumnos);
                asignaturas.AddRange(curso.Asignaturas);

                curso.Alumnos.ForEach(alumno =>
                {
                    evaluaciones.AddRange(alumno.Evaluaciones);
                });                
            });

            dictionary.Add(LlaveDiccionario.Escuela, new List<ObjetoEscuelaBase>() { Escuela });
            dictionary.Add(LlaveDiccionario.Cursos, Escuela.Cursos);
            dictionary.Add(LlaveDiccionario.Evaluacion, evaluaciones);
            dictionary.Add(LlaveDiccionario.Asignatura, asignaturas);
            dictionary.Add(LlaveDiccionario.Alumnos, alumnos);

            return dictionary;

        }

excelente clase yo he aplicado ambas maneras en Linq (funcional) y a codigo imperativo

Yo lo hice de esta forma:

Escuela.Cursos.Cast<ObjetoEscuelaBase>());

            var listatmp = new List<Evaluación>();
            var listatmpas = new List<Asignatura>();
            var listatmpal = new List<Alumno>();

            foreach (var cur in Escuela.Cursos)
            {
                listatmpas.AddRange(cur.Asignaturas);
                listatmpal.AddRange(cur.Alumnos);

                foreach (var alum in cur.Alumnos)
                {
                    listatmp.AddRange(alum.Evaluaciones);
                }

Yo inicialice primero los indices y con listas vacias y luego los fui llenando. Tuve un poco de problemas haciendo los casting, pero al final lo logre

public Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> GetDiccionarioObjetos(){
	var diccionario = new Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>>();
    diccionario.Add(LlaveDiccionario.Escuela, new List<ObjetoEscuelaBase>{Escuela});
    diccionario.Add(LlaveDiccionario.Cursos, Escuela.Cursos.Cast<ObjetoEscuelaBase>());
    diccionario.Add(LlaveDiccionario.Alumnos, new List<ObjetoEscuelaBase>());
    diccionario.Add(LlaveDiccionario.Asignaturas, new List<ObjetoEscuelaBase>());
    diccionario.Add(LlaveDiccionario.Evaluaciones, new List<ObjetoEscuelaBase>());
    foreach(Curso curso in Escuela.Cursos){
        (diccionario[LlaveDiccionario.Alumnos] as List<ObjetoEscuelaBase>).AddRange(curso.Alumnos.Cast<ObjetoEscuelaBase>());
        (diccionario[LlaveDiccionario.Asignaturas] as List<ObjetoEscuelaBase>).AddRange(curso.Asignaturas.Cast<ObjetoEscuelaBase>());
        foreach(Alumno alumno in curso.Alumnos){
            (diccionario[LlaveDiccionario.Evaluaciones] as List<ObjetoEscuelaBase>).AddRange(alumno.Evaluaciones.Cast<ObjetoEscuelaBase>());
        }
    }
    return diccionario;
}

Curso de Debbug. “_”

Lo hice asi en mi caso… porque el error relacionado a “unique keys” me aparecia en asignaturas, estudiantes y examenes

#region Implementing dictionaries
        public Dictionary<DictionaryKeysEnum, IEnumerable<BaseSchool>> GetObjectsDictionary()
        {
            var dictionary = new Dictionary<DictionaryKeysEnum, IEnumerable<BaseSchool>>();
            
            dictionary.Add(DictionaryKeysEnum.School, new[] {School});
            dictionary.Add(DictionaryKeysEnum.Courses, School.Courses);

            var temporaryListSubject = new List<Subject>();
            var temporaryListStudent = new List<Student>();
            var temporaryListExam = new List<Exam>();
            foreach (var course in School.Courses)
            {
                temporaryListSubject.AddRange(course.Subjects);
                temporaryListStudent.AddRange(course.Students);
                foreach (var student in course.Students)
                {
                    temporaryListExam.AddRange(student.Exams);
                }
            }
            dictionary.Add(DictionaryKeysEnum.Subjects, temporaryListSubject);
            dictionary.Add(DictionaryKeysEnum.Students, temporaryListStudent);
            dictionary.Add(DictionaryKeysEnum.Exams, temporaryListExam);

            return dictionary;
        }
        #endregion

me salta el siguiente error:
Excepción no controlada del tipo ‘System.ArgumentException’ en System.Private.CoreLib.dll: ‘An item with the same key has already been added. Key: Evaluacion’

public Dictionary<LlaveDiccionario,IEnumerable<ObjetoEscuelaBase> > GetDiccionariosObjetos()
        {

            var diccionario = new Dictionary<LlaveDiccionario,IEnumerable<ObjetoEscuelaBase>>();
            diccionario.Add(LlaveDiccionario.Escuela,new[]{Escuela});
            diccionario.Add(LlaveDiccionario.Curso,Escuela.Cursos.Cast<ObjetoEscuelaBase>());
            foreach (Curso cur in Escuela.Cursos)
            {
                diccionario.Add(LlaveDiccionario.Asignatura,cur.Asignaturas.Cast<ObjetoEscuelaBase>());
                diccionario.Add(LlaveDiccionario.Alumno,cur.Alumnos.Cast<ObjetoEscuelaBase>());
                foreach (Alumno alum in cur.Alumnos)
                {
                    diccionario.Add(LlaveDiccionario.Evaluacion,alum.Evaluaciones.Cast<ObjetoEscuelaBase>());                }
                }
            return diccionario;
        }

El video no está corriendo para esta clase. “The media playback was aborted due to a corruption problem or because the media used features your browser did not support.” Alguien por favor ayuda con el video de esta clase.

La velocidad del vídeo por x2 realmente sirve?

Hola, yo hice una implementación algo parecida pero diferente en la siguiente manera, cree un arreglo de listas de tres posiciones del tipo ObjetoEscuelaBase:

public Dictionary< LlaveDiccionario, IEnumerable<ObjetoEscuelaBase> > GetDiccionarioObjetos()
        {
            var diccionario = new Dictionary< LlaveDiccionario, IEnumerable<ObjetoEscuelaBase> >();
            List<ObjetoEscuelaBase>[] listasTemporales = new List<ObjetoEscuelaBase>[3];
            listasTemporales[0] = new List<ObjetoEscuelaBase>();
            listasTemporales[1] = new List<ObjetoEscuelaBase>();
            listasTemporales[2] = new List<ObjetoEscuelaBase>();
            diccionario.Add( LlaveDiccionario.Escuela, new List<ObjetoEscuelaBase> { Escuela } );
            diccionario.Add( LlaveDiccionario.Curso, Escuela.Cursos );
            foreach (var curso in Escuela.Cursos)
            {
                listasTemporales[0].AddRange( curso.Alumnos );
                listasTemporales[1].AddRange( curso.Asignaturas );
                foreach (var alumno in curso.Alumnos)
                {
                    listasTemporales[2].AddRange( alumno.Evaluaciones );
                }
            }
            diccionario.Add( LlaveDiccionario.Alumno, listasTemporales[0] );
            diccionario.Add( LlaveDiccionario.Asignatura, listasTemporales[1] );
            diccionario.Add( LlaveDiccionario.Evaluacion, listasTemporales[2] );
            return diccionario;
        }