Ben
Ben

Reputation: 25

Dynamically adding key, value parsed array put into Object.property = value schema

I have an object defined as follows:

public class Variable
{
    public string varName { get; set; }
    public double varVal { get; set; }
    public double varParam { get; set; }

    public Variable(string varName1, double varVal1 = 1, double varParam1 = 0)
    {
        varName = varName1;
        varVal = varVal1;
        varParam = varParam1;
    }
}

I have this object in a list that needs to be accessed by many methods in the parent class as follows:

public static List<Variable> variableList = new List<Variable>();

I have an input on a text file that I'm using .Split(",") to put into a string array in any order and possibly missing key-values (besides name):

varName,Test,varVal,1.0101,varParam,3.03

so in my code, after I use .Split(",") for this text line:

string readKeyvalue[] = { "varName","Test","varVal","1.0101","varParam","3.03" }

I must stress that only varName key-pair will be required in the text file, and all of these can be in any order. I want to put them into object properties in the structure like follows (pseudocode):

variableList[0].varName == Test
variableList[0].varVal == 1.0101
variableList[0].varParam == 3.03

I have failed in my previous efforts to make this possible through sorting the array (which works) and using the following as can be reference in my previous question. This line is for the case of a missing varVal, but sorted into a string array of varName,Test,varParam,3.03:

materialList.Add(new Material(sortedVals[1]) { $sortedVals[2] = Convert.ToDouble(sortedVals[3]) } ) ;

As you can see, this does not work because sortedVals[2] is not recognized by the compiler as a member declarator, and I can find no way (without 2-3 more classes just for converting the string into a property then brute forcing my way through tons of code) to assign all of the available values to properties while skipping the missing ones.

So to clarify, I can't find a way to assign the available properties to an object while disregarding any missing objects without hardcoding in each and every case (which will be very difficult when I have an object with 10-12 properties).

If anyone has any wisdom, I would be very grateful!

Upvotes: 0

Views: 44

Answers (1)

Matt Burland
Matt Burland

Reputation: 45155

So if I'm understanding your question, one approach is to parse your input string into a dictionary. Something like this:

var input = "varName,Test,varVal,1.0101,varParam,3.03";

var grouped = input.Split(',').Select((str,idx) => new {str, idx})
    .GroupBy(g => g.idx / 2)
    .Select(g => g.Select(s => s.str).ToArray());
Console.WriteLine(grouped.First().ToString());
var dictionary = grouped.ToDictionary(g => g[0], k => k[1]);

The idea is to split your string and then group it into pairs of values (grouping by the index / 2 which will truncate because it's integer division). From there you can convert the pairs into arrays (of two values) and then to a dictionary keyed off the first value of each pair.

Then you can populate your object by using the database keys, testing for their presence:

variableList[0].varName = dictionary.TryGetValue("varName", out var s) ? s : null;
variableList[0].varVal = dictionary.TryGetValue("varVal", out var s) ? double.TryParse(s, out var d) ? d : 0.0 : 0.0;
variableList[0].varParam = dictionary.TryGetValue("varParam", out var s) ? double.TryParse(s, out var d) ? d : 0.0;

I used double.TryParse and falling back to 0 if the string is malformed, but you might want to actually handle that differently.

Upvotes: 1

Related Questions