C# 3.0: Должен возвратить дубликаты из Списка <>

Я «решаю» проблему ... люди помогают мне, чтобы найти ответ ...

с display: block; по body > main{

body > main {
margin: 5px;
grid-area: main;

display: block; 
}
19
задан Rui Jarimba 14 April 2013 в 15:31
поделиться

8 ответов

Я непреднамеренно кодировал это вчера, когда я пытался записать "отличный проекцией". Я включал a! когда я не должен иметь, но на этот раз это просто правильно:

public static IEnumerable<TSource> DuplicatesBy<TSource, TKey>
    (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        // Yield it if the key hasn't actually been added - i.e. it
        // was already in the set
        if (!seenKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

Вы затем назвали бы его с:

var duplicates = cars.DuplicatesBy(car => car.Color);
29
ответ дан 30 November 2019 в 02:20
поделиться
var duplicates = from car in cars
                 group car by car.Color into grouped
                 from car in grouped.Skip(1)
                 select car;

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

, Если у Вас есть конкретные требования, о котором Вы хотите сохранить, например, если автомобиль имеет Id, свойство и Вы хочет сохранить автомобиль с самым низким Id, затем Вы могли добавить некоторое упорядочивание там, например,

var duplicates = from car in cars
                 group car by car.Color into grouped
                 from car in grouped.OrderBy(c => c.Id).Skip(1)
                 select car;
17
ответ дан 30 November 2019 в 02:20
поделиться
IEnumerable<Car> GetDuplicateColors(List<Car> cars)
{
    return cars.Where(c => cars.Any(c2 => c2.Color == c.Color && cars.IndexOf(c2) < cars.IndexOf(c) ) );
}    

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

Не уверенный в производительности, все же. Я подозреваю подход с O (1), поиск для дубликатов (как dictionary/hashset метод) может быть быстрее для больших наборов.

3
ответ дан 30 November 2019 в 02:20
поделиться

Вот немного отличающееся решение Linq, что я думаю, делает это более очевидным, что Вы пытаетесь сделать:

var s = from car in cars
    group car by car.Color into g
    where g.Count() == 1
    select g.First();

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

5
ответ дан 30 November 2019 в 02:20
поделиться

Создайте новое Dictionary<Color, Car> foundColors, и List<Car> carsToDelete

Затем Вы выполняете итерации через свой исходный список автомобилей как так:

foreach(Car c in listOfCars)
{
    if (foundColors.containsKey(c.Color))
    {
        carsToDelete.Add(c);
    }
    else
    {
        foundColors.Add(c.Color, c);
    }
}

Затем можно удалить каждый автомобиль, это находится в foundColors.

Вы могли добраться, незначительное повышение производительности путем помещения "удаляют рекордную" логику в if оператор вместо того, чтобы создать новый список, но способ, которым Вы сформулировали вопрос, предложил, чтобы необходимо было собрать их в Списке.

3
ответ дан 30 November 2019 в 02:20
поделиться

Мой ответ берет вдохновение (в этом порядке) от респондентов подписчиков: Joe Coehoorn, Greg Beech и Jon Skeet.

я решил обеспечить полный пример с предположением тем, чтобы быть (для реальной эффективности слова), что у Вас есть статический список автомобильных цветов. Я полагаю, что следующий код иллюстрирует полное решение проблемы в изящном, хотя не обязательно гиперэффективный, способ.

#region SearchForNonDistinctMembersInAGenericListSample
public static string[] carColors = new[]{"Red", "Blue", "Green"}; 
public static string[] carStyles = new[]{"Compact", "Sedan", "SUV", "Mini-Van", "Jeep"}; 
public class Car
{
    public Car(){}
    public string Color { get; set; }
    public string Style { get; set; }
}
public static List<Car> SearchForNonDistinctMembersInAList()
{
    // pass in cars normally, but declare here for brevity
    var cars = new List<Car>(5) { new Car(){Color=carColors[0], Style=carStyles[0]}, 
                                      new Car(){Color=carColors[1],Style=carStyles[1]},
                                      new Car(){Color=carColors[0],Style=carStyles[2]}, 
                                      new Car(){Color=carColors[2],Style=carStyles[3]}, 
                                      new Car(){Color=carColors[0],Style=carStyles[4]}};
    List<Car> carDupes = new List<Car>();

    for (int i = 0; i < carColors.Length; i++)
    {
        Func<Car,bool> dupeMatcher = c => c.Color == carColors[i];

        int count = cars.Count<Car>(dupeMatcher);

        if (count > 1) // we have duplicates
        {
            foreach (Car dupe in cars.Where<Car>(dupeMatcher).Skip<Car>(1))
            {
                carDupes.Add(dupe);
            }
        }
    }
    return carDupes;
}
#endregion

я собираюсь возвратиться через сюда позже и сравнить это решение всего трех из его вдохновения, только контрастировать стили. Это довольно интересно.

0
ответ дан 30 November 2019 в 02:20
поделиться

На самом деле не кодируя его, как насчет алгоритма что-то вроде этого:

  • выполняют итерации через Ваш List<T>, создание Dictionary<T, int>
  • выполняет итерации через Ваш Dictionary<T, int> записи удаления, где эти int> 1

, Что-нибудь в эти Dictionary имеет дубликаты. Вторая часть, где Вы на самом деле удаляете, является дополнительной, конечно. Можно просто выполнить итерации через Dictionary и искать> 1's для принятия мер.

РЕДАКТИРОВАНИЕ: хорошо, я увеличил Ryan, так как он на самом деле дал Вам код. ;)

0
ответ дан 30 November 2019 в 02:20
поделиться

общедоступные статические Дубликаты IQueryable (этот источник IEnumerable), где TSource: IComparable {

if (source == null)   
     throw new ArgumentNullException("source");   
 return source.Where(x => source.Count(y=>y.Equals(x)) > 1).AsQueryable<TSource>();   

}

0
ответ дан 30 November 2019 в 02:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: