#c# #list #duplicates
Вопрос:
{
public static List<string> DuplicateNames(List<Person> a, List<Person> b)
{
List<string> DuplicatePeople = a.Intersect(b).ToList();
}
public static void Main(string[] args)
{
List<Person> personsA = new List<Person>();
personsA.Add(new Person("Emma"));
personsA.Add(new Person("Eva"));
personsA.Add(new Person("Data"));
List<Person> personsB = new List<Person>();
personsB.Add(new Person("Anna"));
personsB.Add(new Person("Eva"));
personsB.Add(new Person("Emma"));
List<string> myDuplicateNames = Program.DuplicateNames(personsA, personsB);
foreach (String s in myDuplicateNames)
{
Console.WriteLine(s);
}
Console.Read();
}
}
class Person
{
private string name;
public Person(string name)
{
Name = name;
}
public string Name { get => name; set => name = value; }
}
Как говорится в названии, я пытаюсь объединить список personA и PersonB в новый список с функцией «Дубликаты имен». Затем я хочу вызвать функцию, которая преобразует повторяющиеся имена в новом списке в «myDuplicatenNames» и распечатывает этот список.
Я довольно новичок в C# и не могу заставить его работать. Любая помощь будет признательна!
Ответ №1:
Ваш код может быть изменен для работы с Intersect
методом, который вы используете в настоящее время. Проблема в том, что в вашей реализации вы пытаетесь сравнить класс, который вы создали: Person
. По умолчанию сравнение выполняется по ссылке, а не по содержимому свойств. Для того, чтобы он работал, вы можете переопределить Equals
его в своем Person
классе:
class Person
{
private string name;
public Person(string name)
{
Name = name;
}
public string Name { get => name; set => name = value; }
public override bool Equals(object obj)
{
return obj is Person person amp;amp;
name == person.name amp;amp;
Name == person.Name;
}
}
Еще одно замечание о вашем DuplicateNames
методе, его следует изменить, сделайте то, что вы хотите, преобразуйте список Person
дубликатов в список дубликатов string
с помощью Select
метода:
public static List<string> DuplicateNames(List<Person> a, List<Person> b)
{
return a.Intersect(b).Select(p => p.Name).ToList();
}
Комментарии:
1. Спасибо за ответ, я возьму ответ и изучу его.
Ответ №2:
1-я проблема: a-это список людей, и вы пытаетесь назначить его списку строк. 2-я проблема: 2 человека с одинаковым именем не равны. Вы можете переопределить Equals, но LINQ предлагает вам более гибкий способ.
public class Person
{
public string Name { get; } // Read-only default property, initialized in constructor.
public Person(string name)
{
Name = name;
}
}
public class Program
{
public static List<string> DuplicateNames(List<Person> a, List<Person> b)
{
// LINQ 1:
List<string> duplicatePeople = a
.Select(a => a.Name) // Projecting a list of persons to a list of strings
.Where(a => b.Select(p => p.Name).Contains(a)) // Check for each item if it's in the list of names of b.
.ToList();
// LINQ 2: Join
var duplicatePeople2 = a.Join(
b, // 2nd List
a => a.Name, // What ist the key of the first list?
b => b.Name, // What ist the key of the second list?
(a, b) => a) // Secting the item of the first list (if you have more properties in class Person, this could be different from the item of the second list)
.Select(p => p.Name) // Again: projecting to a list of strings
.ToList();
return duplicatePeople;
}
public static void Main(string[] args)
{
// List offers an initializer.
var personsA = new List<Person>()
{
new Person("Emma"),
new Person("Eva"),
new Person("Data")
};
var personsB = new List<Person>()
{
new Person("Anna"),
new Person("Eva"),
new Person("Emma")
};
List<string> myDuplicateNames = DuplicateNames(personsA, personsB);
foreach (var s in myDuplicateNames)
{
Console.WriteLine(s);
}
Console.Read();
}
}
Комментарии:
1. Эти ответы, кажется, работают на меня. Это было намного сложнее, чем я представлял себе в своей голове. Я обязательно изучу и изучу то, что вы предоставили. Спасибо!