我有以下数组:
Driver[] predictions = new Driver[6];
predictions[0] = new Driver(10, "Michael Schumacher");
predictions[1] = new Driver(10, "Michael Schumacher");
predictions[2] = new Driver(9, "Fernando Alonso");
predictions[3] = new Driver(8, "Jensen Button");
predictions[4] = new Driver(7, "Felipe Massa");
predictions[5] = new Driver(6, "Giancarlo Fisichella");
我希望获得所有重复项 - 名称一次,然后是重复项所在的位置(索引)。因此,在这种情况下,我希望获得“迈克尔·舒马赫”以及第1和第2位(指数0和1)。
这可以一次完成,还是我需要考虑其他选择?我刚刚在DotNetPearls上看到,与拥有自己的逻辑相比,IndexOf相当慢。
var driversSelectedMoreThanOnceAndTheirPositions = predictions.Select((driver, index) => new { driver, index })
.GroupBy(item => item.driver.Name)
.Where(grp => grp.Count() > 1)
.ToDictionary(g => g.Key, g => g.Select(a => (a.index + 1)).ToList());
答案 0 :(得分:1)
为了利用linq,您可以编写类似下面的内容,它使用Select
的重载,允许您获取元素索引,然后执行GroupBy
操作。
var query =
predictions.Select((driver, index) => new { driver, index })
.GroupBy(item => item.driver.Name)
.Where(grp => grp.Count() > 1)
.Select(grp => new { Name = grp.Key, Indexes = grp.Select(item => item.index) });
这将产生一系列具有属性
的匿名类型对象class Anon
{
public string Name;
public IEnumerable<int> Indexes;
}
您可以在
中使用foreach (var item in query)
{
Console.WriteLine(item.Name);
foreach (int index in item.Indexes)
Console.WriteLine(index);
}
当然,您可以更改分组以获取整个驱动程序对象的方式。
答案 1 :(得分:0)
下面的代码将为您提供一个由驱动程序名称键入的字典,其值为原始数组中的所有位置。它还将为您提供一个唯一的列表(HashSet),其中仅包含在原始数组中多次出现的驱动程序名称。
Driver[] predictions = new Driver[6];
predictions[0] = new Driver(10, "Michael Schumacher");
predictions[1] = new Driver(10, "Michael Schumacher");
predictions[2] = new Driver(9, "Fernando Alonso");
predictions[3] = new Driver(8, "Jensen Button");
predictions[4] = new Driver(7, "Felipe Massa");
predictions[5] = new Driver(6, "Giancarlo Fisichella");
Dictionary<string, List<int>> indicies = new Dictionary<string, List<int>>();
HashSet<string> driversWithDups = new HashSet<string>();
for (int i=0; i<predictions.Length; i++)
{
Driver eachDriver = predictions[i];
if (indicies.ContainsKey(eachDriver.Name))
{
indicies[eachDriver.Name].Add(i);
driversWithDups.Add(eachDriver.Name);
}
else
{
indicies[eachDriver.Name] = new List<int>() {i};
}
}
答案 2 :(得分:0)
鉴于Driver类的明确定义,这应该给你你想要的东西:
Driver[] predictions = new Driver[6];
predictions[0] = new Driver(10, "Michael Schumacher");
predictions[1] = new Driver(10, "Michael Schumacher");
predictions[2] = new Driver(9, "Fernando Alonso");
predictions[3] = new Driver(8, "Jensen Button");
predictions[4] = new Driver(7, "Felipe Massa");
predictions[5] = new Driver(6, "Giancarlo Fisichella");
var ds = predictions.Select((driver, i) => new { Name = driver.Name, Index = i })
.GroupBy(a => a.Name, a => a.Index);