Search code examples
c#linqnested-loops

Linq query to find objects in nested objects


Complete code is attached below. I want to find all Cars objects that has a certain color.

The Vehicles list consists of two lists of type Cars. The Cars lists consist of objects of type Colours.

Instead of using foreach iterations, what would a Linq query look like?

using System.Collections.Generic;

public class Test
{
    public void testitall()
    {
        List<Cars> test = FindCarByColour("Red");
    }

    /// <summary>
    /// Find all cars with property ColourName like colourcriteria
    /// </summary>
    /// <param name="colourcriteria"></param>
    /// <returns></returns>
    private List<Cars> FindCarByColour(string colourcriteria)
    {
     // Populate data classes
        Colours Col1 = new Colours();
        Col1.ColourName ="Red";
        Colours Col2 = new Colours();
        Col2.ColourName ="Blue";
        List<Cars> CarList1 = new List<Cars>();
        CarList1.Add(new Cars { Name = "Saab", ColourProperties = Col1 });
        CarList1.Add(new Cars { Name = "Citroen", ColourProperties = Col2});
        List<Cars> CarList2 = new List<Cars>();
        CarList2.Add(new Cars { Name = "Daf", ColourProperties = Col1 });
        CarList2.Add(new Cars { Name = "Vauxhall", ColourProperties = Col2 });
        List<Vehicles> vehicleList = new List<Vehicles>();
        vehicleList.Add(new Vehicles { Vechicle = "SmallCar", Cars = CarList1 });
        vehicleList.Add(new Vehicles { Vechicle = "MediumCar", Cars = CarList2 });

        // Search 
        List<Cars> ListOfFindings = new List<Cars>();
        foreach (Vehicles vehicleItem in vehicleList)
        {
            foreach (Cars caritem in vehicleItem.Cars)
            {
                if (caritem.Name != null && caritem.ColourProperties.ColourName == colourcriteria)
                {
                    ListOfFindings.Add(caritem);
                }
            }
        }
        return ListOfFindings;
    }

    // Data classes
    public class Vehicles
    {
        public string Vechicle { get; set; }
        public List<Cars> Cars { get; set; }
    }
    public class Cars
    {
        public string Name { get; set; }
        public Colours ColourProperties { get; set; }
    }
    public class Colours
    {
        public string ColourName { get; set; }
    }

}


Solution

  • You could probably use something like:

    var listOfFindings = (from vehicleItem in vehicleList
                          from carItem in vehicleItem.Cars
                          where carItem.Name != null
                          && carItem.ColourProperties.ColourName == colourcriteria
                          select carItem).ToList();
    

    or

    var listOfFindings = vehicleList.SelectMany(vehicleItem => vehicleItem.Cars).Where(carItem => carItem.Name != null && carItem.ColourProperties.ColourName == colourcriteria).ToList();
    

    Depending on what style of Linq you want to use.