我正在为我的网站开发一个包含一些统计数据的部分,并且我有一些麻烦来弄清楚如何获得“受欢迎的东西”(下面的解释):
我有下表:
ID | Spell1ID | Spell2ID
1 | 4 | 12
2 | 4 | 12
3 | 12 | 4
4 | 1 | 8
5 | 3 | 12
6 | 8 | 1
为了获得这些数据,我正在做以下事情:
List<short[]> spellsList = new List<short[]>();
..
using (MySqlDataReader dbReader = Conex.Command.ExecuteReader())
{
while (dbReader.Read())
{
short[] tempArray = new short[2];
tempArray[0] = dbReader.GetInt16("spell1ID");
tempArray[1] = dbReader.GetInt16("spell2ID");
spellsList.Add(tempArray);
}
}
现在,我需要计算哪些值是最常见的(从最常见到较不常见),并且列表中每个数组的值的顺序不应该很重要([4,12]和[12,4]是相同的,因为我实际需要的是SpellID以及它的使用频率,所以对于这个例子,这将是:
1- 4, 12 (3 times)
2- 1,8 (2 times)
3- 3,12
如果可以使用带有lambda表达式的LINQ pref来完成它,那将会很棒。
对不起,如果这令人困惑,英语不是我的第一语言。
答案 0 :(得分:3)
static void Main(string[] args)
{
var spellsList = new List<short[]>();
spellsList.Add(new short[] {4, 12 });
spellsList.Add(new short[] {4, 12 });
spellsList.Add(new short[] {12, 4 });
spellsList.Add(new short[] { 1, 8});
spellsList.Add(new short[] {3, 12});
spellsList.Add(new short[] {8, 1 });
spellsList.Add(new short[] {8, 1 });
spellsList.Add(new short[] {8, 1 });
spellsList.Add(new short[] {8, 1 });
var result = spellsList.Select(s => s[0] > s[1] ? String.Format("{0},{1}", s[0], s[1]) : String.Format("{0},{1}", s[1], s[0]))
.GroupBy(s => s)
.OrderByDescending(g => g.Count())
.ToList();
result.ForEach(g => Console.WriteLine($"{g.Key}: {g.Count()} times"));
Console.Read();
}
答案 1 :(得分:0)
// fake data
var data = @"1 | 4 | 12
2 | 4 | 12
3 | 12 | 4
4 | 1 | 8
5 | 3 | 12
6 | 8 | 1"
.Split('\n')
.Select(x => x.Split(new[] { " | " }, StringSplitOptions.None));
var spellsList = data.Select(x => new[]
{
int.Parse(x[1]), int.Parse(x[2])
});
// query
var combos = spellsList
.GroupBy(spells => string.Join(", ", spells.OrderBy(x => x)), (k, g) => new
{
SpellCombo = k,
CastCount = g.Count(),
})
.OrderBy(x => x.CastCount)
.ToList();
foreach(var combo in combos)
{
Console.WriteLine($"Combo {combo.SpellCombo} is casted {combo.CastCount} times. ");
}