Maro
Maro

Reputation: 2629

C# query with filter condition

I have a list of TransportType to filter from the application should compare the user selection with this list then return only what he selected which should be in the defined list

 private static readonly string[] ValidTransportType = new string[]
    {
        "Cars", 
        "Airplans", 
        "Audi",
        "BMW", 
        "Airbus A333", 
        "Boing 747",
    };

    public static IEnumerable<string> GetSelectedTypes(IEnumerable<string> userSelection )
    {
        var list = (from transport in ValidTransportType
                    where userSelection.Contains(transport)
                    select transport).ToList();

        return list;
    }

for example: if user selected "Car", "Porsche" then the result will be only "Car" because porsche was not defined.

My question is, how can i modify the Linq query to perform the following: If user selected "Cars", "Audi", "BMW" the query returns Cars because cars includes BMW and AUDI, if the user Selects "Audi" and "BMW" then the application will return "Audi" and "BMW" but not "cars" because it was not selected , if user selected "BMW", "AUDI", "Airplanes", "Boing 747" then the application should return list of "BMW", "Audi", "Airplanes" But not "Boing 747" becuase Airplanes includes "Boing 747"

Any Idea?

Edit:

Please notice that the type and type to compare are unkown before runtime, both are coming from exteranl files, example: in my example i put cars, but it can be animal, Technology, person ... etc, that's why i cannot predict the type and create classes upfront.

Upvotes: 0

Views: 2281

Answers (1)

sloth
sloth

Reputation: 101072

It's actually easier without a linq query, but with a plain old foreach loop.

First, let's create a dictionary to group BMW and Audi into a Cars group etc.:

var d = new Dictionary<string, List<string>>();
string[] items = {"Cars,BMW", "Cars,Audi", "Animals,Dog"};
foreach (var item in items)
{
    // TODO: use better variable names
    // you probably use a csv parser for this
    var s = item.Split(',');

    // fill the dictionary. 
    if (!d.ContainsKey(s[0]))
        d[s[0]] = new List<string>();
    d[s[0]].Add(s[1]);
}

Then, the implementation of GetSelectedTypes could look like this:

public static IEnumerable<string> GetSelectedTypes(Dictionary<string, List<string>> validTypes, IEnumerable<string> userSelection )
{
    foreach (var kvp in validTypes)
        // if the key is in userSelection, only return the key, but no items
        if (userSelection.Contains(kvp.Key))
            yield return kvp.Key;
        // if not, only return valid items
        else 
            foreach (var item in kvp.Value)
                if (userSelection.Contains(item))
                    yield return item;
}

simple test:

string[] userSelection = {"Cars", "Audi", "Dog"};
// will be [Cars, Dog], because Cars include Audi
GetSelectedTypes(d, userSelection);

string[] userSelection2 = {"BMW", "Audi", "Dog", "Animals"};
// will be [BMW, Audi, Animals] because Animals include Dog
GetSelectedTypes(d, userSelection2);

Upvotes: 1

Related Questions