Concat, Distinct по строке
От: e.thrash  
Дата: 18.10.23 12:06
Оценка:
Есть такой код простой.
Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.

  Код рабочий
internal class Program
{
    private static void Main(string[] args)
    {
        var dt1 = new dt()
        {
            id = 1,
            ds = "20220101",
            de = "20220202"
        };


        var dt2 = new dt()
        {
            id = 1,
            ds = "20220101",
            de = "20220202"
        };

        var l = new List<dt>();
        l.Add(dt1);
        l.Add(dt2);

        //cnt = 2  ?
        var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds.Concat(d.de)).Distinct().Count() });


     //cnt = 1
        var s2 = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds + d.de).Distinct().Count() }); 
    }
}

class dt
{
    public int id;
    public string ds;
    public string de;
}




тем более в мсдн написано такое

Для объединения строк можно также использовать оператор объединения строк языка, например + в C# и F#, или & и + в Visual Basic. Оба компилятора преобразуют оператор объединения в вызов одной из перегрузок String.Concat.

Re: Concat, Distinct по строке
От: pilgrim_ Россия  
Дата: 18.10.23 12:51
Оценка: 2 (1) +1
Здравствуйте, e.thrash, Вы писали:

ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.


Метод string.Concat статический, у тебя же в 1-м случае вызывается Enumerable.Concat<char>, соотв. Distinct делается для последовательности состоящей из 2-х разных IEnumerable-объектов — отсюда и 2.
Re: Concat, Distinct по строке
От: vmpire Россия  
Дата: 18.10.23 12:54
Оценка: 2 (1) +1
Здравствуйте, e.thrash, Вы писали:

ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.


ET>
ET>internal class Program
ET>{
ET>    private static void Main(string[] args)
ET>    {
ET>        var dt1 = new dt()
ET>        {
ET>            id = 1,
ET>            ds = "20220101",
ET>            de = "20220202"
ET>        };


ET>        var dt2 = new dt()
ET>        {
ET>            id = 1,
ET>            ds = "20220101",
ET>            de = "20220202"
ET>        };

ET>        var l = new List<dt>();
ET>        l.Add(dt1);
ET>        l.Add(dt2);

ET>        //cnt = 2  ?
ET>        var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds.Concat(d.de)).Distinct().Count() });


ET>     //cnt = 1
ET>        var s2 = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds + d.de).Distinct().Count() }); 
ET>    }
ET>}

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

ET>тем более в мсдн написано такое

А это про другой Concat.

Слишком сложно пишете, от того и ошибки.

Попробуйте, например, изменить первый вариант на
var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => new string(d.ds.Concat(d.de).ToArray())).Distinct().Count()});
Отредактировано 18.10.2023 12:58 vmpire . Предыдущая версия . Еще …
Отредактировано 18.10.2023 12:57 vmpire . Предыдущая версия .
Re: Concat, Distinct по строке
От: Разраб  
Дата: 18.10.23 12:57
Оценка: 2 (1) +1
Здравствуйте, e.thrash, Вы писали:

ET>Есть такой код простой.

ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
   var ds = "20220101";
   var de = "20220202";
Console.WriteLine(ds + de);
Console.WriteLine(new String(ds.Concat(de).ToArray()));
Console.WriteLine(string.Concat(ds,de));

У вас Concat из linq вызывается. нужный Concat статик.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Concat, Distinct по строке
От: e.thrash  
Дата: 18.10.23 15:08
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Здравствуйте, e.thrash, Вы писали:


ET>>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.


_>Метод string.Concat статический, у тебя же в 1-м случае вызывается Enumerable.Concat<char>, соотв. Distinct делается для последовательности состоящей из 2-х разных IEnumerable-объектов — отсюда и 2.



да, не обратил внимание сначала. но тут вопросики.

когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?
Re[3]: Concat, Distinct по строке
От: m2user  
Дата: 18.10.23 16:04
Оценка:
ET>да, не обратил внимание сначала. но тут вопросики.

ET>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?


Так работают extension методы.

https://learn.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

Методы расширения позволяют "добавлять" методы в существующие типы без создания нового производного типа, перекомпиляции и иного изменения первоначального типа.
Методы расширения представляют собой разновидность статического метода, но вызываются так же, как методы экземпляра в расширенном типе.
Для клиентского кода, написанного на языках C#, F# и Visual Basic, нет видимого различия между вызовом метода расширения и вызовом методов, определенных в типе.


https://learn.microsoft.com/ru-ru/dotnet/api/system.linq.enumerable.concat?view=net-7.0
public static System.Collections.Generic.IEnumerable<TSource> Concat<TSource> (this
System.Collections.Generic.IEnumerable<TSource> first,
System.Collections.Generic.IEnumerable<TSource> second);

String.Concat статический, поэтому может быть вызван только через имя типа, а не имя экземпляра, в отличие от extension метода IEnumerable<Char>.Concat.
Re[4]: Concat, Distinct по строке
От: e.thrash  
Дата: 18.10.23 20:18
Оценка:
Здравствуйте, m2user, Вы писали:

ET>>да, не обратил внимание сначала. но тут вопросики.


ET>>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?


M>Так работают extension методы.


это всё понятно. вопрос про то почему у меня string, а расширение вызывается для типа ienumerable<char> ?
Re[5]: Concat, Distinct по строке
От: pilgrim_ Россия  
Дата: 18.10.23 20:44
Оценка: 3 (1)
Здравствуйте, e.thrash, Вы писали:

M>>Так работают extension методы.


ET>это всё понятно. вопрос про то почему у меня string, а расширение вызывается для типа ienumerable<char> ?


Строка реализует IEnumerable<char>.
Re[4]: Concat, Distinct по строке
От: Разраб  
Дата: 18.10.23 23:31
Оценка:
Здравствуйте, m2user, Вы писали:

ET>>да, не обратил внимание сначала. но тут вопросики.


ET>>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?


M>Так работают extension методы.


благими намерениями, отличный способ замусорить код. Самого корежит от обилия расширений в редакторе.
☭ ✊ В мире нет ничего, кроме движущейся материи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.