LINQ para Búsquedas
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 65 de 70.
Desafío
Fácil¡Vamos a añadir potentes capacidades de búsqueda a tu Sistema de Biblioteca usando LINQ! Implementarás métodos que permitan a los usuarios encontrar libros por varios criterios: buscando por título, filtrando por autor y encontrando libros disponibles. LINQ hace que estas consultas sean elegantes y legibles.
Continuarás construyendo sobre la estructura de tu proyecto existente:
Book.cs: Mantén tu clase Book con las propiedadesId,Title,AuthoreIsAvailable, junto con los métodosBorrow()yReturn().User.cs: Mantén tu clase User con la funcionalidad de seguimiento de préstamos, incluyendoMaxBooks,CanBorrow()y los métodos para gestionar los libros prestados.Library.cs: Aquí es donde añadirás tus métodos de búsqueda potenciados por LINQ. Además de tu lógica de préstamo existente, implementa estas capacidades de búsqueda:SearchByTitle(string keyword)- Devuelve todos los libros donde el título contiene la palabra clave (sin distinguir entre mayúsculas y minúsculas)GetBooksByAuthor(string author)- Devuelve todos los libros de un autor específico (coincidencia exacta, sin distinguir entre mayúsculas y minúsculas)GetAvailableBooks()- Devuelve todos los libros que están actualmente disponiblesGetBorrowedBooks()- Devuelve todos los libros que están actualmente prestados
Program.cs: Procesa las consultas de búsqueda y muestra los resultados.
Recibirás las siguientes entradas:
- Nombre de la biblioteca
- Número de libros, luego cada libro como
id|title|author - Número de operaciones de préstamo para configurar el estado inicial, luego cada una como
bookId - Un comando de búsqueda en uno de estos formatos:
title|keyword- buscar libros por palabra clave en el títuloauthor|name- obtener libros por autoravailable- obtener todos los libros disponiblesborrowed- obtener todos los libros prestados
Para los resultados de la búsqueda, imprime cada libro coincidente en su propia línea en el formato {Title} by {Author}. Si no hay libros que coincidan, imprime No books found. Los resultados deben imprimirse en el orden en que aparecen en la colección de la biblioteca.
Por ejemplo, si las entradas son:
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|TolkienLa salida debería ser:
The Hobbit by Tolkien
The Lord of the Rings by Tolkien
The Silmarillion by TolkienOtro ejemplo con la misma configuración de biblioteca pero buscando libros disponibles:
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
availableLa salida debería ser:
The Lord of the Rings by Tolkien
Animal Farm by George Orwell
The Silmarillion by TolkienLINQ transforma lo que serían bucles complejos en consultas expresivas y legibles. ¡Métodos como Where() para filtrar y ToList() para materializar los resultados harán que tu implementación de búsqueda sea limpia y fácil de mantener!
Pruébalo tú mismo
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Leer el nombre de la biblioteca
string libraryName = Console.ReadLine();
// Crear una instancia de Library con el nombre de la biblioteca
Library library = new Library(libraryName);
// Leer el número de libros
int numBooks = Convert.ToInt32(Console.ReadLine());
// Leer y añadir libros
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);
}
// Leer el número de operaciones de préstamo para establecer el estado inicial
int numBorrows = Convert.ToInt32(Console.ReadLine());
// Procesar las operaciones de préstamo (solo IDs de libros)
for (int i = 0; i < numBorrows; i++)
{
string bookId = Console.ReadLine();
Book book = library.GetBookById(bookId);
if (book != null)
{
book.IsAvailable = false;
}
}
// Leer el comando de búsqueda
string searchCommand = Console.ReadLine();
// Procesar el comando de búsqueda
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);
}
}
// Imprimir los resultados
if (results.Count == 0)
{
Console.WriteLine("No books found");
}
else
{
foreach (Book book in results)
{
Console.WriteLine($"{book.Title} by {book.Author}");
}
}
}
}
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantes9Argumentos variables
La palabra clave 'params'Parámetros opcionalesArgumentos con nombreSobrecarga de métodos12Proyecto: Sistema de Biblioteca
Estructura del ProyectoModelos de Libro y Usuario