Feedback

C# - Tabelle Datentyp

Veröffentlicht von am 05.09.2015
(1 Bewertungen)
Beispiele:

var t = new Table<int>(new[] { new[] { 1, 2, 5 }, new[] { 5, 3, 5 } });


var t = new Table<int>(3, 3); // Tabellee ist 3x3 groß
t[0, 0] = 5; // 0|0 ist 5


oder

Table<int> t = "[1, 2, 5]\r[5, 3, 5]";


man kann auch einer spalte einen namen geben:

Table<int> t = "first [1, 2, 5]\rsecond [5, 3, 5]";


und so alle einträge in einer spalte bekommen oder setzen:

t["first"]


manuell einfach AddHeaders("first", "second");
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace fsm
{
    [Serializable]
    public class Table<T> : ICloneable, IEquatable<T[][]>, IEnumerable, IDisposable
    {
        private T[][] _data;

        private List<string> Headers { get; set; }
        public int ColumnCount { get; private set; }
        public int RowCount { get; private set; }
        public int Count => ColumnCount + RowCount;

        public Table()
        {
            ColumnCount = 0;
            RowCount = 0;
            Headers = new List<string>();
        }
        public Table(int columnCount, int rowCount)
        {
            _data = new T[columnCount][];

            ColumnCount = columnCount;
            RowCount = rowCount;

            Headers = new List<string>();

            initData(rowCount);
        }
        public Table(T[][] src)
        {
            _data = src;

            ColumnCount = src.Length;
            RowCount = _data[0].Length;
            Headers = new List<string>();
        }
        
        public void Expand(int columns, int rows)
        {
            for (int i = 0; i < columns; i++)
            {
                AddColumn();
            }
            for (int i = 0; i < rows; i++)
            {
                AddRow();
            }
        }
        public void Expand()
        {
            Expand(1, 1);
        }

        public void AddColumn()
        {
            var tmp = new T[ColumnCount + 1][];

            Array.Copy(_data, tmp, ColumnCount);
            tmp[ColumnCount] = new T[RowCount];

            _data = tmp;

            ColumnCount++;
        }
        public void AddRow()
        {
            for (int i = 0; i < _data.Length; i++)
            {
                var l = new List<T>(_data[i]);
                l.Add(default(T));

                _data[i] = l.ToArray();
            }

            RowCount++;
        }
        public void AddHeader(string name)
        {
            Headers.Add(name);
        }
        public void AddHeaders(params string[] headers)
        {
            Headers.AddRange(headers);
        }

        public bool Contains(T value)
        {
            foreach (var item in _data)
            {
                foreach (var l in item)
                {
                    if(l.Equals(value))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        public bool ContainsColumn(T[] column)
        {
            foreach (var c in _data)
            {
                if(c == column)
                {
                    return true;
                }
            }

            return false;
        }
        public bool ContainsRow(T[] row)
        {
            foreach (var c in _data)
            {
                foreach (var r in c)
                {
                    if(row.Equals(r))
                    {
                        return true;
                    }
                }
            }

            return false;
        }      

        public static Table<T> Parse(string src)
        {
            Table<T> ret = new Table<T>();

            if(string.IsNullOrEmpty(src) || !src.Contains("[") || !src.Contains("]"))
            {
                throw new FormatException(nameof(src) + " has invalid format");
            }

            var s = src.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            T[][] result = new T[s.Length][];

            int x = -1;
            foreach (var line in s.Select(i => i.Trim()))
            {
                x++;
                int headerIndex = line.IndexOf('[') - 1;
                string l = null;
                if (headerIndex > -1) {
                    var header =  line.Substring(0, headerIndex);
                    l = line.Remove(0, header.Length + 1);

                    ret.AddHeader(header);
                }
                
                l = l.TrimStart('[').TrimEnd(']');
                var r = new List<T>();
                foreach (var item in l.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(i => i.Trim()))
                {
                    r.Add((T)Convert.ChangeType(item, typeof(T)));
                }
                result[x] = r.ToArray();
            }

            ret._data = result;

            return ret;
        }
        public static bool TryParse(string src, out Table<T> result)
        {
            Table<T> r;
            try
            {
                r = Parse(src);
            }
            catch (Exception)
            {
                result = null;
                return false;
            }

            result = r;
            return true;
        }

        public void Clear()
        {
            _data = new T[ColumnCount][];
            Headers = new List<string>();

            initData(RowCount);
        }
        public void ClearAt(int x, int y)
        {
            this[x, y] = default(T);
        }
        public void ClearAllFrom(string header)
        {
            var hI = getHeaderIndex(header);

            _data[hI] = new T[ColumnCount];
        }

        public T this[int x, int y]
        {
            get
            {
                if (x < 0 || y < 0) throw new IndexOutOfRangeException();

                return _data[x][y];
            }
            set
            {
                _data[x][y] = value;
            }
        }
        public T[] this[string header]
        {
            get
            {
                return _data[getHeaderIndex(header)];
            }
            set
            {
                _data[getHeaderIndex(header)] = value;
            }
        }

        private void initData(int rowCount)
        {
            for (int c = 0; c < ColumnCount; c++)
            {
                for (int r = 0; r < rowCount; r++)
                {
                    _data[c] = new T[ColumnCount];
                }
            }
        }
        private int getHeaderIndex(string header)
        {
            for (int i = 0; i < Headers.Count; i++)
            {
                if (Headers[i] == header)
                {
                    return i;
                }
            }

            throw new Exception("Header '" + header + "' not found");
        }
        private bool hasHeader(int index)
        {
            return index > -1 && index < Headers.Count;
        }

        #region "interface implementations"
        public object Clone()
        {
            return MemberwiseClone();
        }
    
        public bool Equals(T[][] other)
        {
            return _data == other;
        }

        public IEnumerator GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        public void Dispose()
        {
            _data = null;

            GC.SuppressFinalize(this);
        }

        #endregion

        public override string ToString()
        {
            var sb = new System.Text.StringBuilder();

            for (int x = 0; x < ColumnCount; x++)
            {
                if(hasHeader(x))
                {
                    sb.Append(Headers[x] + " ");
                }
                sb.Append("[");
                for (int y = 0; y < RowCount; y++)
                {
                    sb.Append(this[x, y] + ", ");
                }
                sb.Remove(sb.Length - 2, 2);
                sb.Append("]" + '\r');
            }

            sb.Remove(sb.Length - 1, 1);

            return sb.ToString();
        }
        public override bool Equals(object obj)
        {
            return _data == ((Table<T>)obj)._data;
        }
        public override int GetHashCode()
        {
            return _data.GetHashCode();
        }

        #region "Operators"
        public static implicit operator Table<T>(string s)
        {
            return Parse(s);
        }

        public static implicit operator string(Table<T> t)
        {
            return t.ToString();
        }
        #endregion

    }
}
Abgelegt unter table, 2d.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!