Удаление дубликатов из списка - PullRequest
2 голосов
/ 27 мая 2019

Я пытаюсь удалить дубликаты из списка двойных массивов. Я хотел бы сохранить первый экземпляр дубликата, но удалить все найденные после.

Вот мой код:

private static List<double[]> RemoveDupes(List<double[]> locData)
    {
        List<double[]> list = locData;
        while (ContainsDupes(list))
            for (int a = 0; a < list.Count; a++)
                for (int b = 0; b < list.Count; b++)
                    if (a != b && list[a][0] == list[b][0] && list[a][1] == list[b][1])
                        list.RemoveAt(b);

        return list;
    }
private static bool ContainsDupes(List<double[]> list)
    {
        for (int a = 0; a < list.Count; a++)
            for (int b = 0; b < list.Count; b++)
                if (a != b && list[a][0] == list[b][0] && list[a][1] == list[b][1])
                    return true;
        return false;
    }

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

Введите:

{{45.5, 23.6}, {34.54, 98.34}, {45.5, 23.6}}

Желаемый вывод:

{{45.5, 23.6}, {34.54, 98.34}}

(длина двойного [] всегда равна 2)

Ответы [ 2 ]

6 голосов
/ 27 мая 2019

Поскольку вы указали, что массив всегда будет иметь размер 2, я предлагаю вам использовать другой тип данных.Например, tuple было бы более уместным, поскольку на самом деле это пары значений.

Например, вы можете определить набор пар:

List<(double, double)> pairs = new List<(double, double)>(); //C# 7.1+

List<Tuple<double, double>> pairsCollection = new List<Tuple<double, double>>(); // C# 7 or less

Заполните это следующим образом:

pairs.Add((45.5, 23.6));
pairs.Add((34.54, 98.34));
pairs.Add((45.5, 23.6));

И затем, просто используйте метод Distinct, чтобы удалить дубликаты:

pairs.Distinct();

Будет выведено:

{{45.5, 23.6}, {34.54, 98.34}}

Кроме того, если вы не можете изменить тип данных, вы можете проецировать коллекцию в коллекцию пар, и чем ее отличать:

List<double[]> collection = new List<double[]>()
{
    new double[]{45.5, 23.6},
    new double[]{34.54, 98.34},
    new double[]{45.5, 23.6}
};
var pairs = collection.Select(pa => (pa[0], pa[1])); 
var distinctPairs = pairs.Distinct();
0 голосов
/ 27 мая 2019

Вы можете использовать https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sequenceequal?redirectedfrom=MSDN&view=netframework-4.8#System_Linq_Enumerable_SequenceEqual__1_System_Collections_Generic_IEnumerable___0__System_Collections_Generic_IEnumerable___0__

var l = new List<int[]>(){
            new int[]{5,4,3},
            new int[]{5,4,3},
            new int[]{5,4,2},
            };

            var indexStore = new List<int>();

            for (int i = 0; i < l.Count - 1; i++)
            {
                for (int x = i + 1; x < l.Count-1; x++)
                {
                    if (l[i].SequenceEqual(l[x]))
                    {
                        indexStore.Add(x);
                    }
                }
            }

            foreach (var index in indexStore)
            {
                l.RemoveAt(index);
            }

Не удалять при зацикливании, лучше хранить дублирующиеся индексы

...