score:1

Accepted answer

If what you are interested on is merely the variants, you could try:

var selections = source.Select(i => i.Variants.OrderByDescending(v => v.isOrdered));

selections will then be an IEnumerable<IOrderedEnumerable<Variant>> with three enumerations of variants (based on your sample data), ordered in this manner:

True,True,False

True,False,False

True,True,False,False

UPDATE:

OP has updated the question to require the item as well, so...

There are a few ways to go about this. The least OOP-based, least intrusive one would be to grab the item as well as the sorted variant list into an anonymous type:

var selections = source.Select(i => new 
{ 
    Item = i, 
    SortedVariants = i.Variants.OrderByDescending(v => v.isOrdered)
});

In this case, selections will be an IEnumerable<'a> where 'a is the anonymous type. The type will have two properties: the item that the variants belong to as well as a property called SortedVariants.

Then there is the simplest, non-reusable way. Every time you access the variants, sort them:

foreach (var item in source)
{
    var variants = item.Variants.OrderByDescending(v => v.isOrdered);          
    //Do something with the variants
}

A more reusable way is to add another property (or method) to the Variant class that returns the variant list in the desired order:

public class Item
{   
    public List<Variant> Variants;

    public IOrderedEnumerable<Variant> OrderedVariants
    {
        get { return Variants.OrderByDescending(v => v.isOrdered); }
    }

    //OR

    public IOrderedEnumerable<Variant> GetOrderedVariants()
    {
        return Variants.OrderByDescending(v => v.isOrdered);
    }
}

You can then use that property or method instead.

Lastly, if you have the flexibility to change the current design, you can always hide the list behind an interface and implement a method to add:

public class Item
{   
    private List<Variant> _variants = new List<Variant>();
    public IEnumerable<Variant> Variants
    {
        get { return _variants.OrderByDescending(v => v.isOrdered); }            
    }

    public void AddVariant(Variant variant)
    {
        _variants.Add(variant);
    }
}

This would my personal favorite since it provides the variants, satisfies the requirement and hides the details of the implementation.

score:0

I would suggest something like the below.

var orderedItems = Items.OrderBy(item => item.Variants.Where(v => v.isOrdered).Count());

This orders the items by how many of it's variants are ordered. You could replace whatever you like in the where.

score:1

if you only want to sort Variant do this :

var SortedVariantItems= Items.Select(x =>new Item {Variants= x.Variants.OrderByDescending(c => c.isOrdered).ToList()})

and if you want In addition to Variant, Items also be sorted(by Variant) do this:

var SortedItems= Items.Select(x =>new Item {Variants= x.Variants.OrderByDescending(c => c.isOrdered).ToList()}).OrderByDescending(x=>x.Variants.Count(c=>c.isOrdered));

Related Articles