Shanti
Shanti

Reputation: 65

Convert specflow table todictionary

I want to create a dictionary from c# specflow table . I need this as the values in the label and value will change for every feature file.In my current feature file, I have 2 columns.

And I submit with following 
| Label         | Value               |
| Namelabel     | texttoenter123      |
| Email         |[email protected]        |

Corresponding Step.Tried to use linq.

 [When(@"I submit with following ")]

   public void WhenISubmitWithFollowing(Table table)
        {
       //Should be something like this , which convert the table todictionary object
          var x = table.Rows.ToDictionary(k=>k.Keys,k=>k.Values);
        }``

Currently I am getting null in this.Please help.

Upvotes: 5

Views: 6769

Answers (2)

Andreas
Andreas

Reputation: 96

If you want to be flexible with the table column headings:

var x = table.Rows.ToDictionary(r => r[0], r => r[1]);

Otherwise:

var x = table.Rows.ToDictionary(r => r["Label"], r => r["Value"]);

Of if you want a quick extension method to TechTalk.SpecFlow.Table:

static class SpecFlowExtensions
{
    /// <summary>
    /// Converts a two column Gherkin data table to a dictionary
    /// </summary>
    /// <param name="table"></param>
    /// <returns></returns>
    public static Dictionary<string, string> ToDictionary(this Table table)
    {
        if (table == null)
            throw new ArgumentNullException(nameof(table));

        if (table.Rows.Count == 0)
            throw new InvalidOperationException("Gherkin data table has no rows");

        if (table.Rows.First().Count != 2)
            throw new InvalidOperationException($@"Gherkin data table must have exactly 2 columns. Columns found: ""{string.Join(@""", """, table.Rows.First().Keys)}""");

        return table.Rows.ToDictionary(row => row[0], row => row[1]);
    }
}

And to use the extension method:

var data = table.ToDictionary();

Upvotes: 8

jdweng
jdweng

Reputation: 34421

Try following if you have only one value per key

            DataTable dt = new DataTable();
            dt.Columns.Add("Label", typeof(string));
            dt.Columns.Add("Value", typeof(string));


            dt.Rows.Add(new object[] { "Namelabel", "texttoenter123" });
            dt.Rows.Add(new object[] { "Email", "[email protected]" });

            Dictionary<string, string> dict = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Label"), y => y.Field<string>("Value"))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

Use following if more than one value per key

            Dictionary<string, List<string>> dict = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Label"), y => y.Field<string>("Value"))
                .ToDictionary(x => x.Key, y => y.ToList());

Upvotes: 0

Related Questions