styx
styx

Reputation: 1917

Zip array and mixed array in C#

I have these two Lists

the first one is a List<String> propsNames that can look like these:

["Name", "Description", "HardwareID"]

and the other list is List<Object> propValues that can look like these:

["USB Input Device", "USB Input Device", ["USB\\VID_062A&PID_4102&REV_8113", "USB\VID_062A&PID_4102"]]

I want to zip the list and print it key- value(s) pair

var propNamesAndValues = propsNames.Zip(propValues, (pName, pValue) => new { propName = pName, propValue = pValue });   

 foreach (var item in propNamesAndValues)
 {
     sb.AppendLine(item.propName + ": " + item.propValue);                
 }

these will output me (on sb.ToString();)

    Name: USB Input Device
    Description: USB Input Device
    HardwareID: System.String[]

but I want

Name: USB Input Device
Description: USB Input Device
HardwareID: USB\\VID_062A&PID_4102&REV_8113, USB\VID_062A&PID_4102

how can i achieve these?

please note that the propValues may not contain sub-array and if it does it location may vary.

Edit: i cannot change and propValues type because I'm getting the result through reflection and i cannot determine the output before run-time

Upvotes: 0

Views: 337

Answers (2)

sr28
sr28

Reputation: 5106

You need to check whether the propValue is a string[] first before using it, and if so then pull the items out of there. So something like this should work:

var propNamesAndValues = propsNames.Zip(propValues, (pName, pValue) => new { propName = pName, propValue = pValue });

var sb = new StringBuilder();

foreach (var item in propNamesAndValues)
{
    var sb2 = new StringBuilder();
    if (item.propValue.GetType() == typeof(string[]))
    {              
        foreach (var listItem in item.propValue as string[])
        {
            sb2.Append(listItem + ", ");
        }
    }
    else
    {
        sb2.Append(item.propValue);
    }

    sb.AppendLine(item.propName + ": " + sb2.ToString());
}

Upvotes: 2

Aleks Andreev
Aleks Andreev

Reputation: 7054

You need to use string.Join. When iterating through propValues check if item is a string. And if not you can cast it to IEnumerable

Try this code:

var propsNames = new List<string> {"Name", "Description", "HardwareID"};
var propValues = new List<object> {"USB Input Device", "USB Input Device", new List<object> {"USB\\VID_062A&PID_4102&REV_8113", "USB\\VID_062A&PID_4102" }};

var propsAndValues = propsNames.Zip(propValues, (name, value) => new {name, value});
var sb = new StringBuilder();

foreach (var item in propsAndValues)
{
    var value = item.value is string 
      ? item.value 
      : string.Join(", ", (IEnumerable<object>)item.value);
    sb.AppendLine(item.name + ": " + value);
}

Note that this code expect only 2 level nested array. If your propValues may looks like

["1", "2", ["3", ["4", "5"]], "6"]

then you need to parse it recursively

Upvotes: 4

Related Questions