// Copyright 2017-2018 Alexander Luzgarev
using System;
using System.Linq;
namespace MatFileHandler
{
///
/// A better interface for using table objects.
///
public class TableAdapter
{
private readonly IMatObject matObject;
///
/// Initializes a new instance of the class.
///
/// Source table object.
public TableAdapter(IArray array)
{
matObject = array as IMatObject
?? throw new HandlerException("Table adapter must be initialized with a MATLAB object.");
if (matObject.ClassName != "table")
{
throw new ArgumentException("The object provided is not a table.");
}
var cellArray = matObject["varnames"] as ICellArray
?? throw new HandlerException("Table variable names must be in a cell array.");
VariableNames = Enumerable
.Range(0, cellArray.Count)
.Select(i =>
(cellArray[i] as ICharArray ??
throw new HandlerException("Variable name must be a char array.")).String)
.ToArray();
NumberOfVariables = VariableNames.Length;
var props = matObject["props"] as IStructureArray
?? throw new HandlerException("Table properties must be a structure array.");
Description = (props["Description"] as ICharArray
?? throw new HandlerException("Table description must be a char array.")).String;
NumberOfRows = (int)(matObject["nrows"].ConvertToDoubleArray()
?? throw new HandlerException("Cannot find number of rows in a table."))[0];
var rowNamesArrays = matObject["rownames"] as ICellArray
?? throw new HandlerException("Table row names must be a cell array.");
RowNames = Enumerable
.Range(0, rowNamesArrays.Count)
.Select(i => (cellArray[i] as ICharArray
?? throw new HandlerException("Each table row name must be a char array.")).String)
.ToArray();
}
///
/// Gets table description.
///
public string Description { get; }
///
/// Gets the number of rows in the table.
///
public int NumberOfRows { get; }
///
/// Gets the number of variables in the table.
///
public int NumberOfVariables { get; }
///
/// Gets row names.
///
public string[] RowNames { get; }
///
/// Gets variable names.
///
public string[] VariableNames { get; }
///
/// Gets all the data for a given variable.
///
/// Variable name.
/// All data associated with the variable.
public IArray this[string variableName]
{
get
{
var maybeIndex = Enumerable.Range(0, VariableNames.Length)
.Where(i => VariableNames[i] == variableName)
.Select(i => (int?)i)
.FirstOrDefault();
if (!(maybeIndex is int index))
{
throw new IndexOutOfRangeException($"Variable '{variableName}' not found.");
}
var data = matObject["data"] as ICellArray
?? throw new HandlerException("Table data must be stored in a cell array.");
return data[index];
}
}
}
}