diff --git a/ChangeLogs/1.0.2-ChangeLog.md b/ChangeLogs/1.0.2-ChangeLog.md new file mode 100644 index 0000000..d68c370 --- /dev/null +++ b/ChangeLogs/1.0.2-ChangeLog.md @@ -0,0 +1,14 @@ +# V1.0.2 + +## New Properties + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `Headers` | `string[]` | `Array.Empty()` | The table headers. Headers are not required. | +| `Rows` | `List` | `new List()` | All the data rows for the table. Rows are not required. | + +## New Method + +| Method | Description | +|--------|-------------| +| `AddRows(params string[][] rows)` | Adds multiple data rows to the table. Rows are not required. | diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 92da2fa..d0771ce 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -6,6 +6,8 @@ static void Main(string[] args) { WriteDefaultTable(); + WriteDefaultTableWithProperties(); + WriteTableWithStyling(true, true, 10); WriteTableWithStyling(false, true, 10); @@ -35,8 +37,31 @@ private static void WriteDefaultTable() var table = new Table(); table.SetHeaders("Name", "Age", "City"); table.AddRow("Alice Cooper", "30", "New York"); - table.AddRow("Bob", "25", "Los Angeles"); - table.AddRow("Charlie Brown", "47", "Chicago"); + table.AddRows(new string[][] + { + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + }); + + Console.WriteLine(table.ToTable()); + Console.WriteLine(); + } + + private static void WriteDefaultTableWithProperties() + { + Console.WriteLine(); + Console.WriteLine("Default table with properties instead of methods:"); + + var table = new Table + { + Headers = new string[] { "Name", "Age", "City" }, + Rows = new List + { + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + } + }; Console.WriteLine(table.ToTable()); Console.WriteLine(); @@ -65,9 +90,11 @@ private static void WriteTableMoreHeaders() table.SetHeaders("Name", "Age", "City", "Country"); - table.AddRow("Alice Cooper", "30"); - table.AddRow("Bob", "25"); - table.AddRow("Charlie Brown", "47"); + table.AddRows( + new string[] { "Alice Cooper", "30" }, + new string[] { "Bob", "25" }, + new string[] { "Charlie Brown", "47" } + ); Console.WriteLine(table.ToString()); Console.WriteLine(); @@ -82,9 +109,11 @@ private static void WriteTableLessHeaders() table.SetHeaders("Name"); - table.AddRow("Alice Cooper", "30", "New York"); - table.AddRow("Bob", "25", "Los Angeles"); - table.AddRow("Charlie Brown", "47", "Chicago"); + table.AddRows( + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ); Console.WriteLine(table.ToString()); Console.WriteLine(); @@ -154,8 +183,10 @@ private static void WriteTableFluent() var tableString = new Table() .SetHeaders("Name", "Age", "City") .AddRow("Alice Cooper", "30", "New York") - .AddRow("Bob", "25", "Los Angeles") - .AddRow("Charlie Brown", "47", "Chicago") + .AddRows( + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ) .ToTable(); Console.WriteLine(tableString); diff --git a/ConsoleTable.Text/ConsoleTable.Text.csproj b/ConsoleTable.Text/ConsoleTable.Text.csproj index 952c862..640f4f7 100644 --- a/ConsoleTable.Text/ConsoleTable.Text.csproj +++ b/ConsoleTable.Text/ConsoleTable.Text.csproj @@ -5,7 +5,7 @@ ConsoleTable.Text - 1.0.1 + 1.0.2 Bruno Van Thournout A library for creating a formatted string tables with customizable headers, rows, and alignment options. https://github.com/BrunoVT1992/ConsoleTable diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index b52b19b..4db99d4 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -7,10 +7,36 @@ namespace ConsoleTable.Text { public class Table { - private string[] _headers; - private List _rows = new List(); private string _tableCache = null; + private string[] _headers = Array.Empty(); + /// + /// Gets or sets the headers of the table. This is a single optional top row. + /// + public string[] Headers + { + get => _headers; + set + { + _headers = value ?? Array.Empty(); + ClearCache(); + } + } + + private List _rows = new List(); + /// + /// Gets or sets the rows of the table + /// + public List Rows + { + get => _rows; + set + { + _rows = value ?? new List(); + ClearCache(); + } + } + private int _padding = 1; /// /// Gets or sets the amount of padding in spaces left and right of the rows cell content. Default is 1 @@ -63,8 +89,7 @@ public bool RowTextAlignmentRight /// public Table SetHeaders(params string[] headers) { - _headers = headers; - ClearCache(); + Headers = headers; return this; } @@ -73,18 +98,46 @@ public Table SetHeaders(params string[] headers) /// public Table AddRow(params string[] row) { - _rows.Add(row); + if (Rows == null) + Rows = new List(); + + Rows.Add(row); ClearCache(); return this; } + /// + /// Adds multiple rows to the table + /// + public Table AddRows(params string[][] rows) + { + if (rows != null) + { + if (Rows == null) + Rows = new List(); + + Rows.AddRange(rows); + ClearCache(); + } + + return this; + } + /// /// Clears all the rows from the table /// public Table ClearRows() { - _rows.Clear(); - ClearCache(); + if (Rows == null) + { + Rows = new List(); + } + else + { + Rows.Clear(); + ClearCache(); + } + return this; } @@ -256,18 +309,18 @@ public string ToTable() var table = new List(); var firstRowIsHeader = false; - if (_headers?.Any() == true) + if (Headers?.Any() == true) { - table.Add(_headers); + table.Add(Headers); firstRowIsHeader = true; } - if (_rows?.Any() == true) + if (Rows?.Any() == true) { - foreach (var row in _rows) + foreach (var row in Rows) { //Weird behaviour with empty rows - if ((row == null || row.Length <= 0) && _headers?.Length > 0) + if ((row == null || row.Length <= 0) && Headers?.Length > 0) table.AddRange(new string[][] { new string[] { " " } }); else table.Add(row); diff --git a/ConsoleTable.slnx b/ConsoleTable.slnx index 5a0d0db..1328dc0 100644 --- a/ConsoleTable.slnx +++ b/ConsoleTable.slnx @@ -6,6 +6,7 @@ + diff --git a/README.md b/README.md index a50b8e6..c2fb267 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ConsoleTable +# ConsoleTable.Text A lightweight .NET library for creating beautifully formatted console tables with customizable headers, rows, padding, and text alignment. @@ -14,6 +14,9 @@ A lightweight .NET library for creating beautifully formatted console tables wit - Optimized for performance - Support for varying column counts across rows (each row can have its own number of cells). +## Releases +Check releases for the changelog here [https://github.com/BrunoVT1992/ConsoleTable/releases/](https://github.com/BrunoVT1992/ConsoleTable/releases/) + ## Installation ### Package Manager @@ -45,12 +48,16 @@ var table = new Table(); table.SetHeaders("Name", "Age", "City"); // Add rows -table.AddRow("Alice", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie", "35", "Chicago"); +table.AddRow("Alice Cooper", "30", "New York"); + +table.AddRows(new string[][] +{ + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +}); // Display the table -Console.WriteLine(table.ToString()); +Console.WriteLine(table.ToTable()); ``` Output: @@ -72,6 +79,8 @@ Output: | Property | Type | Default | Description | |----------|------|---------|-------------| +| `Headers` | `string[]` | `Array.Empty()` | The table headers. Headers are not required. | +| `Rows` | `List` | `new List()` | All the data rows for the table. Rows are not required. | | `Padding` | `int` | `1` | The number of spaces on each side of cell content | | `HeaderTextAlignmentRight` | `bool` | `false` | When `true`, header text is right-aligned otherwise left aligned | | `RowTextAlignmentRight` | `bool` | `false` | When `true`, row text is right-aligned otherwise left aligned | @@ -82,6 +91,7 @@ Output: |--------|-------------| | `SetHeaders(params string[] headers)` | Sets the table headers. Calling this again will overwrite previous headers. Headers are not required. | | `AddRow(params string[] row)` | Adds a data row to the table. Rows are not required. | +| `AddRows(params string[][] rows)` | Adds multiple data rows to the table. Rows are not required. | | `ClearRows()` | Removes all data rows from the table (headers are preserved). | | `Clear()` | Clear all the headers and rows from the table. | | `ToTable() / ToString()` | Returns the formatted table as a string. | @@ -97,9 +107,11 @@ var table = new Table { Padding = 10 }; table.SetHeaders("Name", "Age", "City"); -table.AddRow("Alice", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie", "47", "Chicago"); +table.AddRows( + new string[] { "Alice", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie", "47", "Chicago" } +); Console.WriteLine(table.ToTable()); ``` @@ -126,9 +138,11 @@ var table = new Table { HeaderTextAlignmentRight = true, RowTextAlignmentRight = table.SetHeaders("Name", "Age", "City"); -table.AddRow("Alice Cooper", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie Brown", "47", "Chicago"); +table.AddRows( + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +); Console.WriteLine(table.ToTable()); ``` @@ -146,6 +160,7 @@ Output: └───────────────┴─────┴─────────────┘ ``` + ### Table with inconsistent columns across rows ```csharp @@ -169,7 +184,7 @@ table.AddRow("Nathalie", "29", "Paris", "France", "Europe", "Earth", "Solar Syst table.AddRow("Mathias", "37", "Oslo", "Norway", "Europe", "Earth", "Solar System"); table.AddRow("Kenny", "55", "Tokyo"); -Console.WriteLine(table.ToString()); +Console.WriteLine(table.ToTable()); ``` Output: @@ -205,6 +220,7 @@ Output: └──────────┴─────┴──────────┘ ``` + ### Write a Table Fluent ```csharp @@ -213,8 +229,10 @@ using ConsoleTable.Text; var tableString = new Table() .SetHeaders("Name", "Age", "City") .AddRow("Alice Cooper", "30", "New York") - .AddRow("Bob", "25", "Los Angeles") - .AddRow("Charlie Brown", "47", "Chicago") + .AddRows( + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ) .ToTable(); Console.WriteLine(tableString); @@ -233,6 +251,7 @@ Output: └───────────────┴─────┴─────────────┘ ``` + ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index d2794df..e9880ea 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -5,35 +5,35 @@ namespace ConsoleTable.Text.Tests; public class TableTests { [Fact] - public void ToString_EmptyTable_ReturnsEmptyString() + public void ToTable_EmptyTable_ReturnsEmptyString() { var table = new Table(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Equal(string.Empty, result); } [Fact] - public void ToString_WithHeadersOnly_ReturnsFormattedTable() + public void ToTable_WithHeadersOnly_ReturnsFormattedTable() { var table = new Table(); table.SetHeaders("Name", "Age"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); } [Fact] - public void ToString_WithRowsOnly_ReturnsFormattedTable() + public void ToTable_WithRowsOnly_ReturnsFormattedTable() { var table = new Table(); table.AddRow("John", "30"); table.AddRow("Jane", "25"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("John", result); Assert.Contains("Jane", result); @@ -42,14 +42,14 @@ public void ToString_WithRowsOnly_ReturnsFormattedTable() } [Fact] - public void ToString_WithHeadersAndRows_ReturnsFormattedTable() + public void ToTable_WithHeadersAndRows_ReturnsFormattedTable() { var table = new Table(); table.SetHeaders("Name", "Age"); table.AddRow("John", "30"); table.AddRow("Jane", "25"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -67,7 +67,7 @@ public void ClearRows_RemovesAllRows() table.ClearRows(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -85,7 +85,7 @@ public void Clear_IsEmpty() table.Clear(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Empty(result); } @@ -99,7 +99,7 @@ public void ClearRows_ThenAddNewRows_Works() table.ClearRows(); table.AddRow("Jane"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.DoesNotContain("John", result); @@ -143,8 +143,8 @@ public void Padding_AffectsTableWidth() table2.SetHeaders("Name"); table2.AddRow("Test"); - var result1 = table1.ToString(); - var result2 = table2.ToString(); + var result1 = table1.ToTable(); + var result2 = table2.ToTable(); // Table with more padding should have longer lines var lines1 = result1.Split('\n', StringSplitOptions.RemoveEmptyEntries); @@ -160,7 +160,7 @@ public void Padding_ZeroPadding_Works() table.SetHeaders("Name"); table.AddRow("Test"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Test", result); @@ -199,12 +199,12 @@ public void RowTextAlignRight_CanBeSet() } [Fact] - public void ToString_WithSingleColumn_ReturnsProperCorners() + public void ToTable_WithSingleColumn_ReturnsProperCorners() { var table = new Table(); table.SetHeaders("Single"); - var result = table.ToString(); + var result = table.ToTable(); // Should have proper corners for single column Assert.Contains("┌", result); @@ -214,7 +214,7 @@ public void ToString_WithSingleColumn_ReturnsProperCorners() } [Fact] - public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() + public void ToTable_MoreHeadersThanRowColumns_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name", "Date", "Number", "Id"); @@ -222,7 +222,7 @@ public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() table.AddRow("name 2", "date 2"); table.AddRow("name 3"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Date", result); @@ -234,14 +234,14 @@ public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() } [Fact] - public void ToString_LessHeadersThanRowColumns_HandlesCorrectly() + public void ToTable_LessHeadersThanRowColumns_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name"); table.AddRow("name 1", "date 1"); table.AddRow("name 2", "date 2", "1"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("name 1", result); @@ -252,14 +252,14 @@ public void ToString_LessHeadersThanRowColumns_HandlesCorrectly() } [Fact] - public void ToString_VaryingRowWidths_HandlesCorrectly() + public void ToTable_VaryingRowWidths_HandlesCorrectly() { var table = new Table(); table.AddRow("short"); table.AddRow("much longer text here"); table.AddRow("mid length"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("short", result); Assert.Contains("much longer text here", result); @@ -273,7 +273,7 @@ public void SetHeaders_OverwritesPreviousHeaders() table.SetHeaders("Old1", "Old2"); table.SetHeaders("New1", "New2"); - var result = table.ToString(); + var result = table.ToTable(); Assert.DoesNotContain("Old1", result); Assert.DoesNotContain("Old2", result); @@ -289,7 +289,7 @@ public void AddRow_MultipleTimes_AddsAllRows() table.AddRow("Row2"); table.AddRow("Row3"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Row1", result); Assert.Contains("Row2", result); @@ -297,13 +297,13 @@ public void AddRow_MultipleTimes_AddsAllRows() } [Fact] - public void ToString_ContainsTableBorderCharacters() + public void ToTable_ContainsTableBorderCharacters() { var table = new Table(); table.SetHeaders("Header"); table.AddRow("Value"); - var result = table.ToString(); + var result = table.ToTable(); // Check for various border characters Assert.Contains("│", result); // Vertical line @@ -313,24 +313,24 @@ public void ToString_ContainsTableBorderCharacters() } [Fact] - public void ToString_MultipleColumns_ContainsMiddleJoint() + public void ToTable_MultipleColumns_ContainsMiddleJoint() { var table = new Table(); table.SetHeaders("Col1", "Col2"); table.AddRow("Val1", "Val2"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("┼", result); // Middle joint } [Fact] - public void ToString_SingleRowSingleColumn_ReturnsValidTable() + public void ToTable_SingleRowSingleColumn_ReturnsValidTable() { var table = new Table(); table.AddRow("X"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("X", result); Assert.Contains("┌", result); @@ -340,13 +340,13 @@ public void ToString_SingleRowSingleColumn_ReturnsValidTable() } [Fact] - public void ToString_EmptyStringValues_HandlesCorrectly() + public void ToTable_EmptyStringValues_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name", "Value"); table.AddRow("", ""); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Value", result); @@ -363,8 +363,8 @@ public void HeaderTextAlignRight_True_AlignsToDifferentPosition() tableRight.SetHeaders("H"); tableRight.AddRow("VeryLongValue"); - var resultLeft = tableLeft.ToString(); - var resultRight = tableRight.ToString(); + var resultLeft = tableLeft.ToTable(); + var resultRight = tableRight.ToTable(); // Both should contain the header, but in different positions Assert.Contains("H", resultLeft); @@ -383,12 +383,190 @@ public void RowTextAlignRight_True_AlignsToDifferentPosition() tableRight.SetHeaders("HeaderHeader"); tableRight.AddRow("V"); - var resultLeft = tableLeft.ToString(); - var resultRight = tableRight.ToString(); + var resultLeft = tableLeft.ToTable(); + var resultRight = tableRight.ToTable(); // Both should contain the value, but in different positions Assert.Contains("V", resultLeft); Assert.Contains("V", resultRight); Assert.NotEqual(resultLeft, resultRight); } + + [Fact] + public void Headers_SetHeadersProperty() + { + var table = new Table(); + table.Headers = new[] { "Name", "Age" }; + + var result = table.ToTable(); + + Assert.Contains("Name", result); + Assert.Contains("Age", result); + } + + [Fact] + public void Headers_SetProperty_OverwritesPreviousHeaders() + { + var table = new Table(); + table.Headers = new[] { "Old1", "Old2" }; + table.Headers = new[] { "New1", "New2" }; + + var result = table.ToTable(); + + Assert.DoesNotContain("Old1", result); + Assert.DoesNotContain("Old2", result); + Assert.Contains("New1", result); + Assert.Contains("New2", result); + } + + [Fact] + public void Headers_SetHeadersProperty_ClearsCache() + { + var table = new Table(); + table.Headers = new[] { "Header1" }; + var firstResult = table.ToTable(); + + table.Headers = new[] { "Header2" }; + var secondResult = table.ToTable(); + + Assert.Contains("Header1", firstResult); + Assert.DoesNotContain("Header1", secondResult); + Assert.Contains("Header2", secondResult); + } + + [Fact] + public void Rows_SetRowsProperty() + { + var table = new Table(); + table.Rows = new List + { + new[] { "John", "30" }, + new[] { "Jane", "25" } + }; + + var result = table.ToTable(); + + Assert.Contains("John", result); + Assert.Contains("Jane", result); + Assert.Contains("30", result); + Assert.Contains("25", result); + } + + [Fact] + public void Rows_SetRowsProperty_OverwritesPreviousRows() + { + var table = new Table(); + table.Rows = new List { new[] { "OldRow" } }; + table.Rows = new List { new[] { "NewRow" } }; + + var result = table.ToTable(); + + Assert.DoesNotContain("OldRow", result); + Assert.Contains("NewRow", result); + } + + [Fact] + public void Rows_SetRowsProperty_ClearsCache() + { + var table = new Table(); + table.Rows = new List { new[] { "Row1" } }; + var firstResult = table.ToTable(); + + table.Rows = new List { new[] { "Row2" } }; + var secondResult = table.ToTable(); + + Assert.Contains("Row1", firstResult); + Assert.DoesNotContain("Row1", secondResult); + Assert.Contains("Row2", secondResult); + } + + [Fact] + public void Rows_SetNull_CreatesEmptyList() + { + var table = new Table(); + table.AddRow("InitialRow"); + table.Rows = null; + + var result = table.ToTable(); + + Assert.Empty(result); + Assert.NotNull(table.Rows); + Assert.Empty(table.Rows); + } + + [Fact] + public void AddRows_AddsMultipleRows() + { + var table = new Table(); + table.AddRows( + new[] { "Row1Col1", "Row1Col2" }, + new[] { "Row2Col1", "Row2Col2" }, + new[] { "Row3Col1", "Row3Col2" } + ); + + var result = table.ToTable(); + + Assert.Contains("Row1Col1", result); + Assert.Contains("Row2Col1", result); + Assert.Contains("Row3Col1", result); + } + + [Fact] + public void AddRows_AppendsToExistingRows() + { + var table = new Table(); + table.AddRow("ExistingRow"); + table.AddRows( + new[] { "NewRow1" }, + new[] { "NewRow2" } + ); + + var result = table.ToTable(); + + Assert.Contains("ExistingRow", result); + Assert.Contains("NewRow1", result); + Assert.Contains("NewRow2", result); + } + + [Fact] + public void AddRows_WithNull_DoesNotThrow() + { + var table = new Table(); + table.AddRow("ExistingRow"); + + var exception = Record.Exception(() => table.AddRows(null)); + + Assert.Null(exception); + var result = table.ToTable(); + Assert.Contains("ExistingRow", result); + } + + [Fact] + public void AddRows_ClearsCache() + { + var table = new Table(); + table.AddRow("InitialRow"); + var firstResult = table.ToTable(); + + table.AddRows(new[] { "NewRow" }); + var secondResult = table.ToTable(); + + Assert.DoesNotContain("NewRow", firstResult); + Assert.Contains("NewRow", secondResult); + } + + [Fact] + public void ToString_ReturnsFormattedTable() + { + var table = new Table(); + table.SetHeaders("Name", "Age"); + table.AddRow("John", "30"); + + var result = table.ToString(); + + Assert.Contains("Name", result); + Assert.Contains("Age", result); + Assert.Contains("John", result); + Assert.Contains("30", result); + } }