LINQ sorting - the first three must be different manufacturers

My OM has a "product" object.
Each product has a "manufacturer identifier" (property, integer).
When I have a list of products to display, the first three are displayed as "great products."
The list is already sorted in a specific sort order, first putting the “recognized” products in the list.

However, now I need to ensure that the recognized products in the listing are from different manufacturers. I want to have a call method to re-sort. Trying to use LINQ to query input "products" and "results"

public List<Product> SetFeatures(List<Product> products, int numberOfFeatures)
{
    List<Product> result;

    // ensure the 2nd product is different manufacturer than the first ....

    // ensure the 3rd product is a different manufacturer than the first two... 

    // ... etc ... for the numberOfFeatures

    return result;

}

Thanks in advance.

:
: " ", ( ). , "", .

n (numberOfFeatures) , .
numberOfFeatures = 3
1 - A (1- )
2 - B ( )
3 - C (3- )
4 - A (... ...)
5 - A (... ...)

. ... ... INPUT
1 - A
2 - A
3 - B
4 - A
5 - F
(... ...)
1 - A (1- )
3 - B ( ... )
5 - F (3- ... )
2 - A (... ...)
4 - A (... ...)

+5
4

, , , , . , , Foo.

        List<Foo> foos = new List<Foo>()
    {
        new Foo() { Baz = 1, Blah = "A"},
        new Foo() { Baz = 2, Blah = "A"},
        new Foo() { Baz = 3, Blah = "B"},
        new Foo() { Baz = 4, Blah = "B"},
        new Foo() { Baz = 5, Blah = "B"},
        new Foo() { Baz = 6, Blah = "C"},
        new Foo() { Baz = 7, Blah = "C"},
        new Foo() { Baz = 8, Blah = "D"},
        new Foo() { Baz = 9, Blah = "A"},
        new Foo() { Baz = 10, Blah = "B"},
    };

    var query = foos.Distinct(new FooComparer()).Take(3).ToList();
    var theRest = foos.Except(query);

    query.AddRange(theRest);

FooComparer

    public class FooComparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        return x.Blah == y.Blah;
    }

    public int GetHashCode(Foo obj)
    {
        return obj.Blah.GetHashCode();
    }
}

(Baz) 1, 3 6, , - .

+3

    public List SetFeatures(List products, int numberOfFeatures)
    {
        var manufacturerProducts =
            from product in products
            group product by product.ManufacturerId into productGroup
            select productGroup.First();

        return manufacturerProducts.Take(numberOfFeatures).ToList();
    }

a >

: . :

return products
    .OrderBy(product => product, new FeaturedProductComparer(numberOfFeatures))
    .ToList();

IComparer<Product> , . 3, , :

private class FeaturedProductComparer : IComparer<Product>
{
    // OrderBy preserves the order of equal elements
    private const int _originalOrder = 0;
    private const int _xFirst = -1;
    private const int _yFirst = 1;

    private readonly HashSet<int> _manufacturerIds = new HashSet<int>();
    private readonly int _numberOfFeatures;

    internal FeaturedProductComparer(int numberOfFeatures)
    {
        _numberOfFeatures = numberOfFeatures;
    }

    public int Compare(Product x, Product y)
    {
        return _manufacturerIds.Count == _numberOfFeatures
            ? _originalOrder
            : CompareManufacturer(x, y);
    }

    private int CompareManufacturer(Product x, Product y)
    {
        if(!_manufacturerIds.Contains(x.ManufacturerId))
        {
            _manufacturerIds.Add(x.ManufacturerId);

            // Sort existing featured products ahead of new ones
            return _manufacturerIds.Contains(y.ManufacturerId) ? _yFirst : _xFirst;
        }
        else if(!_manufacturerIds.Contains(y.ManufacturerId))
        {
            _manufacturerIds.Add(y.ManufacturerId);

            // Sort existing featured products ahead of new ones
            return _manufacturerIds.Contains(x.ManufacturerId) ? _xFirst : _yFirst;
        }
        else
        {
            return _originalOrder;
        }
    }
}
+2

Distinct() , :

, ?

var result = 
        products
            .GroupBy(x => x.Id)
            .Take(numberOfFeatures)
            .Select(x => x.First())
            .Union(products);
return result.ToList();

, GroupBy Union

+1

, , .

, "numberOfFeatures" "", "ManufacturerId" ""?

public List<Product> SetFeatures(List<Product> products, int numberOfFeatures)
{
    return products
        .GroupBy(p => p.ManufacturerId)
        .Take(numberOfFeatures)
        .Select(g => g.First());
}
0

All Articles