所以我有一点学术问题。我能够使用蛮力方法解决这个问题,但我相信它在LINQ中可以更加优雅地解决 - 但是,我找不到这样做的方法。解决方案可以是C#或VB,它是LINQ本身给我带来的麻烦。
我有以下对象:
public class Foo
{
public int FooId {get; set; }
public int Bar {get; set; }
/// <summary>
/// Contains list of FooId
/// </summary>
public int[] Stackability
}
我需要做的是根据Foo
找到Stackability
的所有可能分组(即:可堆叠列表中的公共FooId
),然后选择具有最高总和Bar
。
所以,例如:我的Ios为1,2和3的Foos。
+-------+-----+--------------+
| FooId | Bar | Stackability |
+-------+-----+--------------+
| 1 | 5 | 2, 3 |
+-------+-----+--------------+
| 2 | 2 | 1, 3 |
+-------+-----+--------------+
| 3 | 6 | 1 |
+-------+-----+--------------+
在这个例子中,Foo 1可以与Foo 2和Foo 3堆叠,Foo 2可以与Foo 1和Foo 3堆叠,而Foo 3只能与Foo 1堆叠。
请注意,堆叠必须是倒数(因此即使Foo 2可以与Foo 1和Foo 3堆叠,Foo 3也只能与Foo 1堆叠,这意味着 Foo 2实际上只能堆叠Foo 1 )。
这将为我们提供以下分组及其Bar
的相应总和:
在这种情况下,正确的分组将是Foo 1和Foo 3.
提前致谢!
答案 0 :(得分:0)
如果我正确理解了您的问题,则以下内容将返回正确的分组。
void Main()
{
var data = new[] {
new Foo {FooId = 1, Bar = 5, Stackability = new int[] {2, 3} },
new Foo {FooId = 2, Bar = 2, Stackability = new int[] {1, 3} },
new Foo {FooId = 3, Bar = 6, Stackability = new int[] {1} } };
var result = data
.Select(d => new
{
Foo = d,
Matches = data.Where(dm => dm.Stackability.Contains(d.FooId))
})
.Select(d => new
{
d.Foo,
Narrowed = d.Matches.Where(m => d.Foo.Stackability.Contains(m.FooId))
})
.SelectMany(d => d.Narrowed.Select(n => new { Foos = new List<Int32> { d.Foo.FooId, n.FooId}, BarSum = d.Foo.Bar + n.Bar}))
.OrderByDescending(d => d.BarSum)
.First();
Console.WriteLine($"{{ {String.Join(", ", result.Foos.Select(f => $"Foo {f}"))} }} - Bar == {result.BarSum}");
}
public class Foo
{
public int FooId { get; set; }
public int Bar { get; set; }
/// <summary>
/// Contains list of FooId
/// </summary>
public int[] Stackability { get; set; }
}
它返回以下内容:
{Foo 1,Foo 3}-酒吧== 11