Home > Back-end >  Accesse to jagged arrays in different classes - C#
Accesse to jagged arrays in different classes - C#

Time:08-14

I had to model a system (a library) using jagged arrays.

Each Physical Book must be on a shelf.

A Bookshelf is an array of shelves.

A Catalog is an array of bookshelves.

Therefore, a Catalog "is an array of arrays of arrays" of Physical Books.

I had to do everything using three classes: "PhysicalBook", "Bookshelf" and "Catalog".

public class PhysicalBook{
   public string ID {get; private set;}
   //...
}

public class Bookshelf{
   public PhysicalBook[][] bookshelf;
   //...
}

public class Catalog{
   public Bookshelf[] listBookshelves;
   //...
}

My question is: how can I iterate through each "PhysicalBook" of the jagged array "listBookshelves"?

I want to write a method named "SearchPhysicalBook" inside the class "Catalog" that, given a string "ID", find wheter the associated book is present or not in an instance of "Catalog".

 public bool SearchPhysicalBook(string id)
    {
        for (int i=0; i<this.listBookshelves.Length; i  ) {

            for (int j = 0; j < this.listBookshelves.Length; j  )
            {
                for (int k = 0; k < this.listBookshelves.Length; k  ) {

                        /*if (listBookshelves[i][j][k].ID==id)
                              return true;*/
                }
            }
            
        }
        return false;
    
    }
}

What I commented in this last lines of code is wrong.

Can anyone help me, please?

CodePudding user response:

You can use foreach instead of for, it is more readable, like so:

public PhysicalBook SearchPhysicalBookById(string id, Catalog catalog)
{
    foreach (Bookshelf bookshelf in catalog.listBookshelves)
    {
        foreach (PhysicalBook[] physicalBooksInShelf in bookshelf.bookshelf)
        {
            PhysicalBook book = physicalBooksInShelf.FirstOrDefault(book => book.ID.Equals(id));
            if (book != null)
            {
                return book;
            }
        }
    }

    return null;
}

CodePudding user response:

Often we query such collections with a help of Linq, in your case you can use SelectMany to flatten jagged array:

using System.Linq;

...

public bool SearchPhysicalBook(string id) => listBookshelves 
  .SelectMany(shelf => shelf
     .bookshelf
     .SelectMany(line => line))
  .Any(book => book.ID == id);

In order not to repeat the compicated fragment, you can extract a method:

private IEnumerable<PhysicalBook> AllBooks => listBookshelves 
  .SelectMany(shelf => shelf
     .bookshelf
     .SelectMany(line => line));

And then you can have SearchPhysicalBook as easy as

// If book exists
public bool SearchPhysicalBook(string id) => 
  AllBooks.Any(book => book.ID == id);

// Book if it exists, null if there's no such a book:
public PhysicalBook BookByID(string id) => 
  AllBooks.FirstOrDefault(book => book.ID == id);
  • Related