#c# #list
#c# #Список
Вопрос:
нужно найти редкие книги из списка (редкая книга — это книга, которая находится в одном списке, а не в других) вот мой файл списка:
1;Book1;name1;genre1;publisher1;2015;1000
2;Book2;name2;genre2;publisher2;2015;1000
3;Book3;name3;genre3;publisher3;2015;1000
4;Book4;name4;genre4;publisher4;2015;1000
следующий:
1;Book1;name1;genre1;publisher1;2015;1000
2;Book2;name2;genre2;publisher2;2015;1000
3;Book3;name3;genre3;publisher3;2015;1000
4;Book4;name4;genre4;publisher4;2015;1000
5;Unique;name5;genre5;publisher5;2015;1250
в консоли мне нужно получить уникальное название книги, но я получаю:
1, name1, Book1 , genre1 , publisher1 , 2015 , 1000
2, name2, Book2 , genre2 , publisher2 , 2015 , 1000
3, name3, Book3 , genre3 , publisher3 , 2015 , 1000
4, name4, Book4 , genre4 , publisher4 , 2015 , 1000
5, name5, Unique , genre5 , publisher5 , 2015 , 1250
мой код функции:
public static void RareBook(Padaliniai[] fak)
{
List<Book> RareBooks = new List<Book>();
for (int i = 0; i < 2; i )
{
foreach (Book bok in fak[i].GetBookList())
{
RareBooks.Add(bok);
}
}
for (int i = 0; i < 2; i )
{
foreach (Book a in fak[0].GetBookList())
{
foreach (Book b in fak[1].GetBookList())
{
if (a.Pav == b.Pav)
{
RareBooks.Remove(b);
}
}
}
}
foreach (Book bok in RareBooks)
{
Console.WriteLine("{0}, {1}, {2} , {3} , {4} , {5} , {6}",bok.ISBN,bok.Autorius,bok.Pav,bok.Zanras,bok.Leidykla,bok.Metai,bok.Psl);
}
}
что я делаю не так?
Ответ №1:
Вы добавляете обе записи, поэтому вам нужно удалить обе:
foreach (Book b in fak[1].GetBookList())
{
if (a.Pav == b.Pav)
{
RareBooks.Remove(a);
RareBooks.Remove(b);
}
}
Могу ли я просто добавить, что это не идеальное решение? Я бы использовал некоторую логику LINQ для выполнения выбора, отличного от объединения списков… и переопределил Book
бы методы равенства, чтобы указать, когда две книги являются одной и той же книгой.
Что-то вроде этого:
List<Book> rareBooks = fak[0].GetBookList().Except(fak[1].GetBookList())
.Union(fak[1].GetBookList().Except(fak[0].GetBookList()))
.ToList();
Или даже это:
rarebooks = fak[0].GetBookList().Union(fak[1].GetBookList()).Distinct();
В обоих из вышеперечисленных вам необходимо реализовать IEqualityComparer<Book>
конечно.
Комментарии:
1. Список<T>.Метод Remove (T) Удаляет первое вхождение определенного объекта из списка<T>. Можно также использовать removeAll вместо этого.
Ответ №2:
Я бы предпочел LINQ для такого рода операций:
List<Book> fak0Books = fak[0].GetBookList();
List<Book> fak1Books = fak[1].GetBookList();
List<Book> rareBooks = fak0Books.Where(b0 => fak1Books.All(b1 => b0.Pav != b1.Pav)).
Concat(fak1Books.Where(b1 => fak0Books.All(b0 => b0.Pav != b1.Pav)).
ToList();
Для этого берутся все книги, fak[0]
для которых нет книг с одинаковым Pav
in fak[1]
, и все книги, fak[1]
для которых нет книг с одинаковым Pav
in fak[0]
.