сгруппировать список и получать отличные значения только тогда, когда вход является списком - PullRequest
3 голосов
/ 20 марта 2020

Мне нужна помощь со следующим:

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

см. Фрагменты кода:

список создан из этого класса

public class SD
{
    public string From { get; set; }
    public List<string> To { get; set; }
}

ввод списка может выглядеть следующим образом:

var unsortedList = new List<SD>
{
    new SD {From = "a", To = new List<string>{ "b" } },
    new SD {From = "b", To = new List<string>{ "a" } },
    new SD {From = "a", To = new List<string>{ "b", "c" } },
    new SD {From = "a", To = new List<string>{ "b" } },
    new SD {From = "a", To = new List<string>{ "c" } },
};

До того, как To в классе был списком и просто строкой, приведенный ниже код работал отлично. Было бы возвращено 4 записи, так как записи 1 и 4 равны (и, конечно, третья запись будет иметь только одну строку).

var sortedList = unsortedList.GroupBy(x => new { x.From, x.To }).Select(group => group.First()).ToList();

Я играл с orderby, group и hashsets, но ни одна из них не кажется на работу.

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

Вы можете объединить список To в строку и использовать его как часть ключевого селектора в методе GroupBy. Затем выберите первый элемент в каждой группе, чтобы получить список SD элементов без дубликатов

var sortedList = unsortedList.GroupBy(x => new {x.From, To = string.Join(",", x.To)})
    .Select(g => g.First())
    .ToList();

foreach (var item in sortedList) 
    Console.WriteLine($"{item.From} {string.Join(",", item.To)}");

. Будет получен следующий вывод

a b
b a
a b,c
a c
1 голос
/ 20 марта 2020

Вы можете создать пользовательский IEqualityComparer<T> здесь:

public class MyComparer : IEqualityComparer<SD>
{
    public bool Equals(SD x, SD y)
    {
        return x.From == y.From && x.To.SequenceEqual(y.To);
    }

    public int GetHashCode(SD obj)
    {
        return obj.From.GetHashCode();
    }
}

Затем применить этот компаратор к Distinct() для удаления дубликатов:

var noDuplicates = unsortedList.Distinct(new MyComparer());

foreach (var item in noDuplicates)
{
    Console.WriteLine($"From={item.From} To={string.Join(", ", item.To)}");
}

// From=a To=b
// From=b To=a
// From=a To=b, c
// From=a To=c
...