Многомерная структура данных в C # - PullRequest
2 голосов
/ 08 июня 2009

Я хочу построить структуру данных, которая в основном представляет собой матрицу строк со следующим:

  1. Растущее количество рядов
  2. ИСПРАВЛЕНО № столбцов

Я хочу иметь возможность получить все, что находится в конкретной строке или столбце, с помощью вызова метода, который принимает целую строку no и номер int col в качестве аргумента. Кроме того, я хочу иметь возможность установить значение столбца, используя строку и номер столбца.

Я мог бы сделать это сам, но я открыт, чтобы посмотреть, что могут сделать другие люди ...

РЕДАКТИРОВАТЬ Извините, список столбцов будет исправлен, моя ошибка: - (

Ответы [ 6 ]

5 голосов
/ 08 июня 2009

DataTable и DataSet (в основном набор таблиц данных) будут хорошо работать для того, что вы ищете.

Затем вы можете получить доступ к вашим данным (после того, как вы настроите столбцы и добавите свои строки данных) с помощью следующего синтаксиса:

datatable.rows(index)("ColumnName")

или

datatable.rows(rowindex)(columnindex)
3 голосов
/ 08 июня 2009

Если вам нужно более двух измерений или вы хотите более общее решение, вы можете сделать так, чтобы оно работало с List<List<T>>, вложенным так глубоко, как требуется, и обернутым в пользовательский тип, если вам нужна более конкретная функциональность или хотите более простые вызовы методов.

3 голосов
/ 08 июня 2009

Похоже, таблица данных будет самым легким вариантом.

2 голосов
/ 08 июня 2009

Если вы хотите, чтобы он расширялся в обоих направлениях, тогда DataTable - не лучший выбор.

Для интерфейса вы можете использовать свойство индексатора:

class Foo 
{   
    public string this[int x, int y]
    {
        get { return GetData(x,y); }
    }
}

Для внутреннего хранилища лучший вариант немного зависит от ожидаемого использования, то есть будет много пустых ячеек. Вы можете определить

struct Index { public readonly int X, Y; }

и переопределить члены Equals () и GetHashCode (). На SO недавно было несколько вопросов по этому поводу.

После этого используйте Dictionary < Index, string>

Вам все равно придется управлять пределами строк и столбцов и, возможно, перехватывать получение пустых ячеек.

2 голосов
/ 08 июня 2009

Если бы я хотел / должен был свернуть свой собственный (скажем, я не хотел иметь дело с тем, что DataTable / DataSet), то я бы написал что-то около List<List<T>> (или List<List<object>>) как список строк, а затем столбцы с логикой, чтобы списки оставались прямоугольными.

  • AddRow() добавит новую запись внешнего списка.
  • AddColumn() добавит новый элемент во все списки во внутреннем списке.
  • this[int row, int col] будет иметь доступ к this._Data[row][col].

Нечто подобное.

Переключитесь на Dictionary<K, List<V>>, если мне нужны именованные столбцы (тогда списки содержат данные строк для этого столбца).

2 голосов
/ 08 июня 2009

Как насчет того, чтобы что-то основывать на Dictionary<System.Drawing.Point, string>? Так что вы можете написать;

stringGrid.Add(new Point(3,4), "Hello, World!");

Создайте класс, содержащий такой словарь, и тогда вы получите то, что ищете, почти бесплатно. Что-то вроде (не проверено)

class StringGrid
{
    Dictionary<System.Drawing.Point, string> grid;

    public StringGrid
    {
        this.grid = new Dictionary<System.Drawing.Point, string>();
    }

    public string Get(int x, int y)
    {
        string result = null;
        grid.TryGetValue(new Point(x,y), out result);
        return result;
    }

    public void Set(int x, int y, string content)
    {
        var pos = new Point(x,y);
        if (grid.ContainsKey(pos))
        {
            if (content == null)
            {
                // no content, so just clear the cell.
                grid.remove(pos);
            }
            else
            {
                // add new content
                grid[pos].Value = content;
            }  
        } 
        else if (content != null)
        {
            // new non-null content
            grid.add(pos, content);
        }
    }
}

РЕДАКТИРОВАТЬ: Кроме того, если вы хотите получить действительно вспышку;

  • заменить словарь на SortedList<,>
  • замените System.Drawing.Point вашей собственной структурой, которая реализует IComparable

Таким образом, список будет внутренне упорядочен по строкам, а затем по столбцам, делая простой цикл foreach, достаточный для перебора всех значений в первой строке, затем значений во второй и т. Д. Позволяет конвертировать в и `IEnumerable`` - или коллекцию строк.

...