0

I have a class which has two objects with in it. For example:

public class Animal
{
    public Carnivorous MeatEater { get; set; }
    public Herbivorous VegEater { get; set; }
    public Animal()
    {           
        this.MeatEater = new Carnivorous();
        this.VegEater = new Herbivorous();
    }
}

Carnivorous and Herbivorous have a Category property.

I populated this class with a list of data from my database which is stored in either MeatEater or VegEater. I need to get a distinct list of Category from both and MeatEater and VegEater combined. How can I get this list?

Thanks!

6
  • 1
    how you define your Category class? Commented Jul 17, 2013 at 15:18
  • 10
    ...huh. I kinda thought animals "were" meat eaters or veg eaters, rather than "having" meat eaters or veg eaters. This organization feels difficult to wrap my head around; I'd expect MeatEater to be an interface. Commented Jul 17, 2013 at 15:18
  • Just to make sure, this list will contain only 0 (no MeatEater or VegEater object present), 1 (either only MeatEater or VegEater has been assigned, or they both have the same category), or 2 distinct categories will be returned here, right? There's no hidden information that "carnivorous" is a list or something? Commented Jul 17, 2013 at 15:18
  • Sorry, If i am not clear. Commented Jul 17, 2013 at 15:29
  • Sorry, If i am not clear. Based on the data validation, i store in meateater or vegeater. for eg. meateater has 2 records: "Trex", a description, "Very Large" (category) & "Lion", a desc, "Medium". veg eater has 2 records: "Cow", a desc, "Medium" and "Lamb", a desc, "Small". I have to get a distinct list with "large", "Medium" and "Small". Hope I am Clear now. Commented Jul 17, 2013 at 15:36

3 Answers 3

2

If I understood your question correctly, here you go: (this is assuming Category is a string, else you also have to overload Equals in your categories class):

var result = myList.SelectMany(GetValidCategories).Where(s => s != null)
                   .Distinct();

A needed function:

public static IEnumerable<string> GetValidCategories(Animal a)
{
    List<string> categories = new List<string>();
    if (a.MeatEater != null) categories.Add(a.MeatEater.Category);
    if (a.VegEater != null) categories.Add(a.VegEater.Catergory);
    return categories;
}

HOWEVER, this is not a good design. Animals are meat and/or veg eaters. They do not have them.

A better design would be this:

[Flags] public enum AnimalType { Carnivorous = 1, Herbivorous = 2, Ominovorous = 3 }
public class Animal
{
    public AnimalType Type { get; set; }
    public string Category { get; set; }
    //all the other members that Herbivorous + Carnivorous share,
    //so pretty much all of them really.
}

Then, it would be much easier:

var result = myList.Select(a => a.Category).Where(s => s != null).Distinct();
Sign up to request clarification or add additional context in comments.

4 Comments

Omnivores would like a word with your assumption. :)
@Moo-Juice [Flags] would like to have a word with yours. :P
I meant, your line "Animals are meat or veg eaters"... surely "and/or" is better... as they can be both :)
Actually, extending it.. using your Flags solution.. enum AnimalType { Carnivorous = 1, Herbivorous = 2, Ominovorous = 3 }. Problem solved! :)
0

At least one basic approach is to first select them indpendently then union.

using System.Linq;

var query1 = (from animal in myList
    select animal.MeatEater.Category).Distinct();

var query2 = (from animal in myList
    select animal.VegEater.Category).Distinct();

var result = query1.Union(query2);

Comments

0

You can add all the categories from meat eaters to a list and all the categories from veg eaters to the same list if the category is not already present.

var lstCategories = new List<string>();

foreach(string category in animal.MeatEater.Category)
    if(!lstCategories.Contains(category))
        lstCategories.add(category);

foreach(string category in animal.VegEater.Category)
    if(!lstCategories.Contains(category))
        lstCategories.add(category);

so finally the lstCategories will have distinct set of combined Categories at the end.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.