検索のための LINQ
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 65/70。
チャレンジ
簡単LINQを使用して、図書館システムに強力な検索機能を追加しましょう!タイトルによる検索、著者によるフィルタリング、利用可能な本の検索など、さまざまな基準で本を見つけることができるメソッドを実装します。LINQを使用することで、これらのクエリをエレガントで読みやすく記述できます。
既存のプロジェクト構造を引き続き構築していきます:
Book.cs:Id、Title、Author、IsAvailableプロパティ、およびBorrow()とReturn()メソッドを持つ Book クラスを保持します。User.cs:MaxBooks、CanBorrow()、および貸出中の本を管理するメソッドを含む、貸出追跡機能を持つ User クラスを保持します。Library.cs: ここに LINQ を活用した検索メソッドを追加します。既存の貸出ロジックに加えて、以下の検索機能を実装してください:SearchByTitle(string keyword)- タイトルにキーワードが含まれるすべての本を返します(大文字と小文字を区別しません)GetBooksByAuthor(string author)- 特定の著者のすべての本を返します(完全一致、大文字と小文字を区別しません)GetAvailableBooks()- 現在利用可能なすべての本を返しますGetBorrowedBooks()- 現在貸出中のすべての本を返します
Program.cs: 検索クエリを処理し、結果を表示します。
以下の入力を受け取ります:
- 図書館名
- 本の数、その後に各本を
id|title|authorの形式で入力 - 初期状態を設定するための貸出操作の数、その後に各操作を
bookIdとして入力 - 以下のいずれかの形式の検索コマンド:
title|keyword- タイトルのキーワードで本を検索author|name- 著者名で本を取得available- すべての利用可能な本を取得borrowed- すべての貸出中の本を取得
検索結果については、一致する各本を {Title} by {Author} の形式で1行ずつ出力してください。一致する本がない場合は、No books found と出力してください。結果は、図書館のコレクションに表示される順序で出力する必要があります。
例えば、入力が以下の場合:
City Library
5
B001|The Hobbit|Tolkien
B002|The Lord of the Rings|Tolkien
B003|1984|George Orwell
B004|Animal Farm|George Orwell
B005|The Silmarillion|Tolkien
2
B001
B003
author|Tolkien出力は以下のようになります:
The Hobbit by Tolkien
The Lord of the Rings by Tolkien
The Silmarillion by Tolkien同じ図書館の設定で、利用可能な本を検索する場合の別の例:
City Library
5
B001|The Hobbit|Tolkien
B002|The Lord of the Rings|Tolkien
B003|1984|George Orwell
B004|Animal Farm|George Orwell
B005|The Silmarillion|Tolkien
2
B001
B003
available出力は以下のようになります:
The Lord of the Rings by Tolkien
Animal Farm by George Orwell
The Silmarillion by TolkienLINQは、複雑になりがちなループを表現力豊かで読みやすいクエリに変換します。フィルタリングのための Where() や、結果を具体化するための ToList() などのメソッドを使用することで、検索の実装をクリーンでメンテナンスしやすいものにできます!
自分で試してみよう
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// 図書館名を読み込む
string libraryName = Console.ReadLine();
// 図書館名を使用して Library インスタンスを作成する
Library library = new Library(libraryName);
// 本の数を読み込む
int numBooks = Convert.ToInt32(Console.ReadLine());
// 本を読み込んで追加する
for (int i = 0; i < numBooks; i++)
{
string bookInput = Console.ReadLine();
string[] bookParts = bookInput.Split('|');
string bookId = bookParts[0];
string bookTitle = bookParts[1];
string bookAuthor = bookParts[2];
Book book = new Book(bookId, bookTitle, bookAuthor);
library.AddBook(book);
}
// 初期状態を設定するために貸出操作の数を読み込む
int numBorrows = Convert.ToInt32(Console.ReadLine());
// 貸出操作を処理する(本 ID のみ)
for (int i = 0; i < numBorrows; i++)
{
string bookId = Console.ReadLine();
Book book = library.GetBookById(bookId);
if (book != null)
{
book.IsAvailable = false;
}
}
// 検索コマンドを読み込む
string searchCommand = Console.ReadLine();
// 検索コマンドを処理する
List<Book> results = new List<Book>();
if (searchCommand == "available")
{
results = library.GetAvailableBooks();
}
else if (searchCommand == "borrowed")
{
results = library.GetBorrowedBooks();
}
else if (searchCommand.Contains("|"))
{
string[] parts = searchCommand.Split('|');
string searchType = parts[0];
string searchValue = parts[1];
if (searchType == "title")
{
results = library.SearchByTitle(searchValue);
}
else if (searchType == "author")
{
results = library.GetBooksByAuthor(searchValue);
}
}
// 結果を出力する
if (results.Count == 0)
{
Console.WriteLine("No books found");
}
else
{
foreach (Book book in results)
{
Console.WriteLine($"{book.Title} by {book.Author}");
}
}
}
}
}