我的OM有一个“产品”对象 每个产品都有一个'制造商ID'(属性,整数) 当我有一个要显示的产品列表时,前三个显示为“特色产品” 该列表已按特定排序顺序排序,将“特色”产品放在列表中的第一位。
但是,我现在需要确保列表中的特色产品来自不同的制造商。我想有一个方法来调用这个重新排序。试图利用LINQ来查询输入'产品'和'结果'
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;
}
提前致谢。
澄清:
原始列表按特定顺序排列:“最畅销”,最高排名(降序排列)。生成的列表应保持此顺序,但调整或移动“向上”项目除外,以便不同的制造商可以看到顶部 n 功能。
如果项目的第一个 n (numberOfFeatures)都有不同的制造商,则根本不需要更改列表。
例如如果numberOfFeatures = 3
产品1 - 制造商A(第1特征)
产品2 - 制造商B(第二特征)
产品3 - 制造商C(第3特征)
产品4 - 制造商A(......未经检查......)
产品5 - 制造商A(......未经检查......)
e.g。调整案例......例如......
输入列表
产品1 - 制造商A
产品2 - 制造商A
产品3 - 制造商B
产品4 - 制造商A
产品5 - 制造商F
(...我们希望...)
产品1 - 制造商A(第1特征)
产品3 - 制造商B(第二个特征......向上移动)
产品5 - 制造商F(第3个特征......向上移动)
产品2 - 制造商A(...推下列表......)
产品4 - 制造商A(......按下列表......)
答案 0 :(得分:3)
我认为Bryan很好地封装了排序逻辑,这不是我想做的事情。无论如何,我想用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转移到顶部,其余的按照原来的顺序。
答案 1 :(得分:2)
<击> 撞击>
<击>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(); }击>
<击> 撞击>
编辑:问题实际上是关于列表的自定义排序。我选择描述比较本身,并使用它来排序:
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 :(得分:1)
编辑结果不需要Distinct()
,修改后的代码:
这是你想要的吗?
var result =
products
.GroupBy(x => x.Id)
.Take(numberOfFeatures)
.Select(x => x.First())
.Union(products);
return result.ToList();
答案 3 :(得分:0)
如果我理解正确,我认为这对你有用。
您是否正在使用订购列表“产品”询问具有不同“ManufacturerId”的“Product”的第一个“numberOfFeatures”是什么?
public List<Product> SetFeatures(List<Product> products, int numberOfFeatures)
{
return products
.GroupBy(p => p.ManufacturerId)
.Take(numberOfFeatures)
.Select(g => g.First());
}