C # Best way to store strings from input file for manipulation and use?

I have a file of line blocks, each of which ends with a specific keyword. I currently have a stream reader installed, which adds each line of the file to the list up to the end of the current block (the line contains a keyword indicating the end of the block).

listName.Add(lineFromFile);

Each block contains information, for example. Book bookName, Author AuthorName, Journal JournalName, etc. Thus, each block hypothetically represents one element (book, magazine, conference, etc.).

Now, when about 50 or so blocks of information (elements) I need a way to store information, so I can manipulate it and store each author (s), title, page, etc. and know what information comes with which element, etc ..

When typing, I came up with the idea of ​​saving each element as an object of the "Item" class, but with potentially several authors I'm not sure how to achieve this, because I thought maybe using a counter to name a variable, for example

int i = 0;
String Author[i] = "blahblah";
i++;

But as far as I know, this is not permissible? So my question basically is what will be the easiest / easiest way to store each element so that I can manipulate the lines to store each element for later use.

@yamen is an example file:

Author Bond, james
Author Smith John A
Year 1994
Title For beginners
Book Accounting
Editor Smith Joe
Editor Doe John
Publisher The University of Chicago Press
City Florida, USA
Pages 15-23
End

Author Faux, M
Author Sedge, M
Author McDreamy, L
Author Simbha, D
Year 2000
Title Medical advances in the modern world
Journal Canadian Journal of medicine
Volume 25
Pages 1-26
Issue 2
End


Author McFadden, B
Author Goodrem, G
Title Shape shifting dinosaurs
Conference Ted Vancouver
City Vancouver, Canada
Year 2012
Pages 2-6
End
+3
source share
8

. , . , , AddData . .

using System;
using System.Collections.Generic;
using System.IO;

namespace MutiItemDict
{
    class MultiDict<TKey, TValue>  // no (collection) base class
    {
        private Dictionary<TKey, List<TValue>> _data = new Dictionary<TKey, List<TValue>>();

        public void Add(TKey k, TValue v)
        {
            // can be a optimized a little with TryGetValue, this is for clarity
            if (_data.ContainsKey(k))
                _data[k].Add(v);
            else
                _data.Add(k, new List<TValue>() { v });
        }

        public List<TValue> GetValues(TKey key)
        {
            if (_data.ContainsKey(key))
                return _data[key];
            else
                return new List<TValue>();
        }
    }

    class BookItem
    {
        public BookItem()
        {
            Authors = new List<string>();
            Editors = new List<string>();
        }

        public int? Year { get; set; }
        public string Title { get; set; }
        public string Book { get; set; }
        public List<string> Authors { get; private set; }
        public List<string> Editors { get; private set; }
        public string Publisher { get; set; }
        public string City { get; set; }
        public int? StartPage { get; set; }
        public int? EndPage { get; set; }
        public int? Issue { get; set; }
        public string Conference { get; set; }
        public string Journal { get; set; }
        public int? Volume { get; set; }

        internal void AddPropertyByText(string line)
        {
            string keyword = GetKeyWord(line);
            string data = GetData(line);
            AddData(keyword, data);
        }

        private void AddData(string keyword, string data)
        {
            if (keyword == null)
                return;

            // Map the Keywords to the properties (can be done in a more generic way by reflection)
            switch (keyword)
            {
                case "Year":
                    this.Year = int.Parse(data);
                    break;
                case "Title":
                    this.Title = data;
                    break;
                case "Book":
                    this.Book = data;
                    break;
                case "Author":
                    this.Authors.Add(data);
                    break;
                case "Editor":
                    this.Editors.Add(data);
                    break;
                case "Publisher":
                    this.Publisher = data;
                    break;
                case "City":
                    this.City = data;
                    break;
                case "Journal":
                    this.Journal = data;
                    break;
                case "Volume":
                    this.Volume = int.Parse(data);
                    break;
                case "Pages":
                    this.StartPage = GetStartPage(data);
                    this.EndPage = GetEndPage(data);
                    break;
                case "Issue":
                    this.Issue = int.Parse(data);
                    break;
                case "Conference":
                    this.Conference = data;
                    break;
            }
        }

        private int GetStartPage(string data)
        {
            string[] pages = data.Split('-');
            return int.Parse(pages[0]);
        }

        private int GetEndPage(string data)
        {
            string[] pages = data.Split('-');
            return int.Parse(pages[1]);
        }

        private string GetKeyWord(string line)
        {
            string[] words = line.Split(' ');
            if (words.Length == 0)
                return null;
            else
                return words[0];
        }

        private string GetData(string line)
        {
            string[] words = line.Split(' ');
            if (words.Length < 2)
                return null;
            else
                return line.Substring(words[0].Length+1);
        }
    }

    class Program
    {
        public static BookItem ReadBookItem(StreamReader streamReader)
        {
            string line = streamReader.ReadLine();
            if (line == null)
                return null;

            BookItem book = new BookItem();
            while (line != "End")
            {
                book.AddPropertyByText(line);
                line = streamReader.ReadLine();
            }
            return book;
        }

        public static List<BookItem> ReadBooks(string fileName)
        {
            List<BookItem> books = new List<BookItem>();
            using (StreamReader streamReader = new StreamReader(fileName))
            {
                BookItem book;
                while ((book = ReadBookItem(streamReader)) != null)
                {
                    books.Add(book);
                }
            }
            return books;
        }

        static void Main(string[] args)
        {
            string fileName = "../../Data.txt";
            List<BookItem> bookList = ReadBooks(fileName);

            MultiDict<string, BookItem> booksByAutor = new MultiDict<string, BookItem>();
            bookList.ForEach(bk =>
                    bk.Authors.ForEach(autor => booksByAutor.Add(autor, bk))
                );

            string author = "Bond, james";
            Console.WriteLine("Books by: " + author);
            foreach (BookItem book in booksByAutor.GetValues(author))
            {
                Console.WriteLine("    Title : " + book.Title);
            }

            Console.WriteLine("");
            Console.WriteLine("Click to continue");
            Console.ReadKey();
        }
    }
}

, , XML. :

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfBookItem >
  <BookItem>
    <Year>1994</Year>
    <Title>For beginners</Title>
    <Book>Accounting</Book>
    <Authors>
      <string>Bond, james</string>
      <string>Smith John A</string>
    </Authors>
    <Editors>
      <string>Smith Joe</string>
      <string>Doe John</string>
    </Editors>
    <Publisher>The University of Chicago Press</Publisher>
    <City>Florida, USA</City>
    <StartPage>15</StartPage>
    <EndPage>23</EndPage>
  </BookItem>
  <BookItem>
    <Year>2000</Year>
    <Title>Medical advances in the modern world</Title>
    <Authors>
      <string>Faux, M</string>
      <string>Sedge, M</string>
      <string>McDreamy, L</string>
      <string>Simbha, D</string>
    </Authors>
    <StartPage>1</StartPage>
    <EndPage>26</EndPage>
    <Issue>2</Issue>
    <Journal>Canadian Journal of medicine</Journal>
    <Volume>25</Volume>
  </BookItem>
  <BookItem>
    <Year>2012</Year>
    <Title>Shape shifting dinosaurs</Title>
    <Authors>
      <string>McFadden, B</string>
      <string>Goodrem, G</string>
    </Authors>
    <City>Vancouver, Canada</City>
    <StartPage>2</StartPage>
    <EndPage>6</EndPage>
    <Conference>Ted Vancouver</Conference>
  </BookItem>
</ArrayOfBookItem>

:

using (FileStream stream =
    new FileStream(@"../../Data.xml", FileMode.Open,
        FileAccess.Read, FileShare.Read))
        {
            List<BookItem> books1 = (List<BookItem>)serializer.Deserialize(stream);
        }
+2

- , SO ( SO: https://meta.stackexchange.com/questions/128548/what-stack-overflow-is-not).

, , , , / ( ). , . , [first name/initial] [middle names] [surname].

: Dictionary Linq. Linq .

Info :

public class Info
{
   public string Title { get; private set; }
   public string BookOrJournal { get; private set; }
   public IEnumerable<string> Authors { get; private set; }
   //more members of pages, year etc.
   public Info(string stringFromFile)
   {
     Title = /*read book name from stringFromFile */;
     BookOrJournalName = /*read journal name from stringFromFile */;
     Authors = /*read authors from stringFromFile */;
   }
}

, stringFromFile , , .

:

Dictionary<string, List<Info>> infoByAuthor = 
  new Dictionary<string, List<Info>>(StringComparer.OrdinalIrgnoreCase);

OrdinalIgnoreCase - , .

List<string>, listName.Add, :

List<Info> tempList;
Info tempInfo;
foreach(var line in listName)
{
  if(string.IsNullOrWhiteSpace(line))
    continue;
  tempInfo = new Info(line);
  foreach(var author in info.Authors)
  {
    if(!infoByAuthor.TryGetValue(author, out tempList))
      tempInfo[author] = tempList = new List<Info>();
    tempList.Add(tempInfo);
  }
}

, KeyValuePair<string, List<Info>> Key, , Value Info, . , AuthorName , , "jon skeet" "jon skeet" , Info.

, Info , (, ..).

, Linq, :

var grouped = listName.Where(s => !string.IsNullOrWhiteSpace(s))
  .Select(s => new Info(s))
  .SelectMany(i => 
    s.Authors.Select(ia => new KeyValuePair<string, Info>(ia, i))
  .GroupBy(kvp => kvp.Key, kvp => kvp.Value, StringComparer.OrdinalIgnoreCase);

, Key - , - Info . , " ".

+4

, :

class Book {
    string Title;
    int PageCount;
}

Book[] lines = Book[myFile.LineCount]; List<Book>, [] (lines[34] 34- 34- ).

System.Data.DataTable , , . DataTable .

:

DataTable dt = new DataTable();
DataTable.Columns.Add("bookName");

DataRow dr = dt.NewRow();
dr["bookName"] = "The Lost Island";
dt.Rows.Add(dr);

//You can access last row this way: 
dt.Rows[dt.Rows.Count-1]["bookName"].

DataTable , , SQL.

: , , @AndrasZoltan, , , .

+2

Book

public class Book
 {
    public string Name { get; set; }
    public string Author { get; set; }
    public string Journal { get; set; }

 }

List<Book>

var books = new List<Book>();
books.Add(new Book { Name = "BookName", Author = "Some Auther", Journal = "Journal" });
+2

:

public struct BookInfo
    {
        public string Title;
        public string Journal;
    }

:

var dict = new Dictionary<Author, BookInfo>();

, , , . - .

+2

. , . , concurrency , .


. SQL , , .

  • - . .
  • , String.IndexOf() String.Split() .
  • SQL, LINQ , Zoltan LINQ, .
+2

, , , , . , .

public IList<Entry> ParseEntryFile(string fileName)
{
    ...
    var entries = new List<Entry>();

    foreach(var line in file)
    {
        var entry = new Entry();
        ...
        entries.Add(entry);
    }
    return entries;
}


public class Entry
{
    public Book BookEntry { get; set; }
    public Author AuthorEntry { get; set; }
    public Journal JournalEntry { get; set; }
}

public class Book
{
    public string Name{ get; set; }
    ...
}

public class Author
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

...
+1

:

class BookItem
        {
            public string Name { get; set; }
            public string Author { get; set; }
        }

:

var books = new List<BookItem>();
while (NotEndOfFile())
{
    BookItem book= ReadBookItem(...)
    books.Add(book);
}

Once you have this list, you can create multi-valued dictionaries and have quick access to any item using any key. For example, to find a book by its author:

var booksByAuthor = new MultiDict<string, BookItem>();

add items to the dictionary:

books.ForEach(bk => booksByAuthor.Add(bk.Author, bk));

and then you can iterate over it:

string autorName = "autor1";
Console.WriteLine("Books by: " + autorName);
            foreach (BookItem bk1 in booksByAutor)
            {
                Console.WriteLine("Book: " + bk1.Name);
            }

I got a basic dictionary for several subjects:

Multi-valued dictionary?

This is my implementation:

class MultiDict<TKey, TValue>  // no (collection) base class
        {
            private Dictionary<TKey, List<TValue>> _data = new Dictionary<TKey, List<TValue>>();

            public void Add(TKey k, TValue v)
            {
                // can be a optimized a little with TryGetValue, this is for clarity
                if (_data.ContainsKey(k))
                    _data[k].Add(v);
                else
                    _data.Add(k, new List<TValue>() { v });
            }

            // more members

            public List<TValue> GetValues(TKey key)
            {
                if (_data.ContainsKey(key))
                    return _data[key];
                else
                    return new List<TValue>();
            }

        }
+1
source

All Articles