У нас не получилось загрузить Disqus. Если вы модератор, пожалуйста посмотрите наше руководство по устранению неисправностей.
Спасибо Виталий, ваши комментарии на сайте самые полезные пожалуй.
Касательно последнего примера про выборку сложных объектов.
Метод Equals по умолчанию работает с object типом, из-за чего каждый раз будет происходить боксинг-анбоксинг при проверка каждого из элементов списка, что не самым лучшим образом влияет на производительность.
Нужно реализовать интерфейс IEquatable<t>, чтобы решить эту проблему (это вариант Eqauls с универсальным типом)
Person[] students = { new Person("Tom"), new Person("Bob"), new Person("Sam") };
Person[] employees = { new Person("Tom"), new Person("Bob"), new Person("Mike") };
// объединение последовательностей
var people = students.Union(employees);
foreach (Person person in people)
Console.WriteLine(person.Name);
class Person : IEquatable<person>
{
public string Name { get; }
public Person(string name) => Name = name;
public bool Equals(Person? obj)
{
if (obj is null) return false;
return obj.Name == Name;
}
public override int GetHashCode() => Name.GetHashCode();
}
В этом случае боксинг и анбоксинг происходить не будет. Вот более подробно про это - https://learn.microsoft.com...
Кто может, разъясните пожалуйста, зачем в последнем примере нам переопределять в классе методы Equals() GetHashCode(). Когда пробую без них, то списки просто добавляются как при Concat(). Не могу понять механизм. Админ, автор, гуру (не знаю как правильно тебя назвать) расскажи плиззззз.
Для сравнения объектов в последовательностях применяются реализации методов GetHeshCode() и Equals(). Поэтому если мы хотим работать с последовательностями, которые содержат объекты своих классов и структур, то нам необходимо определить для них подобные методы:
еквалс сравнивает ссылки. они всегда разные. поэтому переопределяем
все классы - производные от object, у которого и определены методы Equals() и GetHashCode(). Скорее всего при использовании запросов без явного переопределения работает версия методов, определённая в object
https://uploads.disquscdn.c...
Ещё описка
https://uploads.disquscdn.c...
Мелкая опечатка) результирующая
с помощью linq можно сравнивать коллекции внутри коллекции? т.е. сравнивать коллекции, которые являются полем обьекта составляющего другую коллекцию.
Да, можно. SelectMany из подтемы "проекция данных" Вам в помощь
Еще можно сказать, что record классы уже сами по себе генерируют метод Equals, в котором сравнение двух records производится на основе их значений. То есть в классах record мы не сможем переопределять метод Equals:
Person[] students = { new Person("Kurulko", 27), new Person("Kurulko", 18), new Person("Father", 25) };
Person[] employees = { new Person("Chmo", 15), new Person("Kurulko", 18), new Person("Loh", 228) };
foreach (var item in students.Union(employees))
Console.WriteLine(item);
Console.WriteLine(new string('*',10));
foreach (var item in students.Except(employees))
Console.WriteLine(item);
Console.WriteLine(new string('*', 10));
foreach (var item in students.Intersect(employees))
Console.WriteLine(item);
record Person(string Name, int Age)
{
public override int GetHashCode()
=> HashCode.Combine(Name, Age);
public override string ToString()
=> $"Name:{Name} - Age:{Age}";
}
/*
Будет:
Name:Kurulko - Age:27
Name:Kurulko - Age:18
Name:Father - Age:25
Name:Chmo - Age:15
Name:Loh - Age:228
**********
Name:Kurulko - Age:27
Name:Father - Age:25
**********
Name:Kurulko - Age:18
*/
И без метода GetHashCode, будет работать аналогично
Было бы неплохо, если бы вставили такие же картинки с объединением, пересечением и разностью коллекций как в swift-e:
https://uploads.disquscdn.c...
Симметрическая разность в C#:
string[] soft = { "Microsoft", "Google", "Apple" };
string[] hard = { "Apple", "IBM", "Samsung" };
var union = soft.Union(hard);
var intersect = soft.Intersect(hard);
var symmetricDifference = union.Except(intersect);
foreach (string item in symmetricDifference)
Console.WriteLine(item);
/*
Будет:
Microsoft
Google
IBM
Samsung
*/
А почему это называется множеством?
string[] soft = { "Microsoft", "Google", "Apple"};
Сюда ведь можно напихать дубликатов:
string[] soft = { "Microsoft", "Google", "Apple", "Apple", "Apple"};
а во множестве по определению все элементы уникальны
немного переиначил статью, убрав вообще упоминание о множествах
да, с одной стороны так, но с другой стороны, microsoft также именует их "Операции над множествами" set operators) например, https://docs.microsoft.com/...
неплохо было бы рассказать об использовании LINQPad, если у Вас есть опыт его использования.
LINQPad зачетная программка, компилит всё без создания солюшена, а рассказывать особо нечего, ставите и будет Вам шасце))
https://uploads.disquscdn.c...
А я просто создал пустой проект в Visual Studio и перезатираю его новыми примерами. Никаких левых прог не нужно.
А можно как-то объединить списки через элемент? Например
{1,2,3} {4,5,6} {7,8,9} ... -> {1,4,7,... 2,5,8,... 3,6,9,...}
можно написать свой метод, который бы проходил по спискам и объединял их через элемент
То есть вложенные циклы, или как?
да, можно и через вложенные циклы
а если без циклов можно пример, что-то ничего в голову не приходит?
int[][] a = {
new int[] { 1, 2, 3, 4 },
new int[] { 5, 6 },
new int[] { 7, 8, 9 }
};
var res = a.SelectMany((x, i) => x.Select((y, k) => ((int order, int value))(k * a.Length + i, y)))
.OrderBy(x => x.order).Select(x => x.value);
Console.WriteLine(string.Join(", ", res));
мне кажется читабельнее будет просто вложенные циклы сделать, чем это городить. Да и быстрее
где можно найти подробности по синтаксису, подскажите)
Что-то точно будет вложено. Если не циклы, то функции ( как в примере Тимофея )
Пара слов о перечисленных в статье методах. Для определения эквивалентности они используют методы GetHeshCode() & Equals(). Если вам нужно работать с коллекцией объектов вашего класса, то эти методы, возможно, придется в нём переопределить.