Nandish Y
Nandish Y

Reputation: 21

Use of SelectMany

Here in below code we can show difference between Select and SelectMany operator.

Is there any way to avoid the common skills? For example if two employees have the C# skill then I want to print them only once.

namespace LinqOperators
{
    class Employee
    {
        public string Name { get; set; }
        public List<string> Skills { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Employee> employees = new List<Employee>();
            Employee emp1 = new Employee { Name = "Deepak", Skills = new List<string> { "C", "C++", "Java" } };//Adding Skills List to Employee List i.e List of List
            Employee emp2 = new Employee { Name = "Karan", Skills = new List<string> { "SQL Server", "C#", "ASP.NET" } };

            Employee emp3 = new Employee { Name = "Lalit", Skills = new List<string> { "C#", "ASP.NET MVC", "Windows Azure", "SQL Server" } };

            employees.Add(emp1);
            employees.Add(emp2);
            employees.Add(emp3);

            // Query using Select()
            IEnumerable<List<String>> resultSelect = employees.Select(e => e.Skills);

            Console.WriteLine("**************** Select ******************");

            // Two foreach loops are required to iterate through the results
            // because the query returns a collection of arrays.
            foreach (List<String> skillList in resultSelect)
            {
                foreach (string skill in skillList)
                {
                    Console.WriteLine(skill);
                }
                Console.WriteLine();//To differntiate Two Skill Lists
            }

            // Query using SelectMany()
            IEnumerable<string> resultSelectMany = employees.SelectMany(emp => emp.Skills);

            Console.WriteLine("**************** SelectMany ******************");

            // Only one foreach loop is required to iterate through the results 
            // since query returns a one-dimensional collection.
            foreach (string skill in resultSelectMany)
            {
                Console.WriteLine(skill);
            }

            Console.ReadKey();
        }
    }

} 

Upvotes: 0

Views: 3376

Answers (2)

Martin Capodici
Martin Capodici

Reputation: 1514

You can use .Distinct() to remove duplicates

Upvotes: 1

Ian
Ian

Reputation: 30813

SelectMany will flatten your IEnumerable such that it won't produce IEnumerable of IEnumerables but IEnumerable:

IEnumerable<IEnumerable<string>> skills; //not this [[C#, Java], [C, C++, Java, C#]]
IEnumerable<string> skills; //but this [C#, Java, C, C++, Java, C#]

You could use Distinct in your resultSelectMany to get common skill only once.

resultSelectMany = resultSelectMany.Distinct(); //[C#, Java, C, C++]

Or to put it in the same line:

// Query using SelectMany()
IEnumerable<string> resultSelectMany = employees.SelectMany(emp => emp.Skills).Distinct();

Upvotes: 4

Related Questions