diff --git a/MatFileHandler.Tests/MatFileReaderTests.cs b/MatFileHandler.Tests/MatFileReaderTests.cs index b424227..9000225 100755 --- a/MatFileHandler.Tests/MatFileReaderTests.cs +++ b/MatFileHandler.Tests/MatFileReaderTests.cs @@ -326,6 +326,24 @@ namespace MatFileHandler.Tests Assert.That(obj[2]["x"].ConvertToDoubleArray(), Is.EqualTo(new[] { -2.0 })); } + [Test] + public void TestTable() + { + var matFile = GetTests("good")["table"]; + var obj = matFile["table_"].Value as IMatObject; + var table = new TableAdapter(obj); + Assert.That(table.NumberOfRows, Is.EqualTo(3)); + Assert.That(table.NumberOfVariables, Is.EqualTo(2)); + Assert.That(table.Description, Is.EqualTo("Some table")); + Assert.That(table.VariableNames, Is.EqualTo(new[] { "variable1", "variable2" })); + var variable1 = table["variable1"] as ICellArray; + Assert.That((variable1[0] as ICharArray).String, Is.EqualTo("First row")); + Assert.That((variable1[1] as ICharArray).String, Is.EqualTo("Second row")); + Assert.That((variable1[2] as ICharArray).String, Is.EqualTo("Third row")); + var variable2 = table["variable2"]; + Assert.That(variable2.ConvertToDoubleArray(), Is.EqualTo(new[] { 1.0, 3.0, 5.0, 2.0, 4.0, 6.0 })); + } + private static AbstractTestDataFactory GetTests(string factoryName) => new MatTestDataFactory(Path.Combine(TestDirectory, factoryName)); diff --git a/MatFileHandler.Tests/test-data/good/table.mat b/MatFileHandler.Tests/test-data/good/table.mat new file mode 100644 index 0000000..20018a4 Binary files /dev/null and b/MatFileHandler.Tests/test-data/good/table.mat differ diff --git a/MatFileHandler/TableAdapter.cs b/MatFileHandler/TableAdapter.cs new file mode 100644 index 0000000..0901f66 --- /dev/null +++ b/MatFileHandler/TableAdapter.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; + +namespace MatFileHandler +{ + public class TableAdapter + { + private readonly IMatObject matObject; + + public TableAdapter(IArray array) + { + matObject = array as IMatObject; + if (matObject?.ClassName != "table") + { + throw new ArgumentException("The object provided is not a table."); + } + var cellArray = matObject["varnames"] as ICellArray; + VariableNames = Enumerable + .Range(0, cellArray.Count) + .Select(i => (cellArray[i] as ICharArray).String) + .ToArray(); + NumberOfVariables = VariableNames.Length; + var props = matObject["props"] as IStructureArray; + Description = (props["Description"] as ICharArray).String; + NumberOfRows = (int) matObject["nrows"].ConvertToDoubleArray()[0]; + var rowNamesArrays = matObject["rownames"] as ICellArray; + RowNames = Enumerable + .Range(0, rowNamesArrays.Count) + .Select(i => (cellArray[i] as ICharArray).String) + .ToArray(); + } + + public int NumberOfRows { get; } + + public string[] RowNames { get; } + + public int NumberOfVariables { get; } + + public string[] VariableNames { get; } + + 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; + return data[index]; + } + } + + public string Description { get; } + } +}