Нужен эффективный способ вернуть все дубликаты из списка

Я собираюсь работать с коллекцией, в которой около 500 000 предметов, и я ищу достойный способ получить все дубликаты. После просмотра этот пост я видите, что наиболее популярным решением является использование хешированного набора. Но что, если я хочу получить все Машины красного цвета, а не только Машины 4 и Машины 5?

Car1.Color = Red;

Car2.Color = Blue;

Car3.Color = Green;

Car4.Color = Red;

Car5.Color = Red;

Учитывая проблему, что было бы достаточно быстрым способом сделать это?

РЕДАКТИРОВАТЬ: я увидел в этом посте, что приведенный ниже код можно легко изменить в соответствии с моими потребностями. И я не уверен, что есть действительно лучший способ решить проблему, но я оставлю пост просто для того, чтобы посмотреть.

var duplicates = from car in cars
                 group car by car.Color into grouped
                 from car in grouped
                 select car;

person Eric    schedule 08.06.2012    source источник
comment
Этот ответ от Джона Скита. Потому популярен.   -  person Nikhil Agrawal    schedule 08.06.2012


Ответы (3)


Вы можете использовать метод расширения Enumerable.ToLookup, чтобы сгруппировать автомобили по цвету и получить все автомобили один цвет:

var cars = new List<Car> { car1, car2, car3, car4, car5 };
var lookup = cars.ToLookup(car => car.Color);
var redCars = lookup[Red];
// redCars == { car1, car4, car5 }
person dtb    schedule 08.06.2012
comment
Спасибо, я никогда не замечал этот метод раньше! - person Eric; 08.06.2012
comment
Это работает, если он знает, что у красного есть дубликаты, но что, если он не знает, у кого есть дубликаты? Что, если был продублирован синий цвет, и эта информация не была известна до времени выполнения? - person Joel Etherton; 08.06.2012

Вы можете использовать группу по значению

class Car {
    public Color { get; set; }
}

void Main()
{
     List<Car> cars = GetList(); // not important
     var grouped = cars.GroupBy(c=>c.Color);
     var duplicates = cars.Where(g=>g.Count()>1);

}
person Steve B    schedule 08.06.2012

Вы можете изучить создание различных таблиц поиска с помощью словаря. Например, если вы хотите выполнить поиск в Car.Color, у вас будет Dictionary>, поэтому каждый раз, когда добавляется новый автомобиль, вы также добавляете словарь Color.

Это связано с дополнительным использованием памяти и дополнительным временем, чтобы получить выгоду от более быстрого поиска, и имеет смысл, только если вы собираетесь искать коллекции автомобилей по одному и тому же ключевому полю.

В противном случае лучше использовать Enumerable.ToLookup(). Пожалуйста, смотрите эту ссылку для объяснения того, как работает ToLookup():

http://msdn.microsoft.com/en-us/library/bb549073.aspx

person Chris    schedule 08.06.2012