简体   繁体   中英

how to use string.join to join all values from an object array?

I have the same situation as this user how to use string.join to join value from an object array? in this question. However, I want to join all values from the object instead of only 1 value.

To recap my question: I have an array of object eg:

MyObject[] objs;

and within MyObject it contains 3 string property,

object[0].stringValue1
object[0].stringValue2
object[0].stringValue3

If I want to join the whole array of objects by all of their stringValues (stringValues1,2 and 3), how can I do it?

I think selector doesn't allow me to select several elements, then how to use string.join to join several values from an object array?

See below for example usage of the two extension methods provided in the implementation section below. The first allows you to select the properties to include, and the second includes all string properties of the object in the source collection which I believe is the exact answer to your question.

Example Usage

Note, the resulting output from the two examples below are ordered differently as a result of how each implementation works, however the results are otherwise identical as a result of the first example specifying all string properties on the MyObj sample type

// Test Object
public class MyObj
{
    public MyObj(string prop1, string prop2, string prop3)
    {
        Prop1 = prop1;
        Prop2 = prop2;
        Prop3 = prop3;
    }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
}

// Sample Data
var list = new List<MyObj> {
    new MyObj("A1", "B1", "C1"),
    new MyObj("A1", "B2", "C2"),
    new MyObj("A3", "B3", "C3") 
};

Samples using above object and data


// Example #1 - All properties separated by single separator
Console.WriteLine(list.Join(colSeparator: ','));
// RESULT: A1,A1,A3,B1,B2,B3,C1,C2,C3

// Example #2 - Object property separator, and different object separator
Console.WriteLine(list.Join(colSeparator: ',', rowSeparator: '\n'));

// RESULT: A1,B1,C1
           A1,B2,C2
           A3,B3,C3

Implementation

public static class EnumerableStringJoinExtension
{
    public static string Join<T>(this IEnumerable<T> values, char colSeparator, char? rowSeparator = null)
    {
        var strProperties = typeof(T).GetProperties().Where(r=>r.PropertyType == typeof(string));
        var sb = new StringBuilder();
        foreach(var val in values)
                sb.Append(string.Join(colSeparator, strProperties.Select(r=> r.GetValue(val)))).Append(rowSeparator ?? colSeparator);
        sb.Remove(sb.Length - 1, 1);
        return sb.ToString();
    }
}

A possible way to solve it is to first create an array of each object's properties (using .Select() ), and then flatten the resulting property arrays by using .SelectMany() . Both of those methods are found in the System.Linq namespace. The resulting IEnumerable<string> object's items can then be joined using string.Join() .

If MyObject is defined as

class MyObject
{
    public string First { get; set; }
    public string Second { get; set; }
    public string Third { get; set; }
}

and you define objects as

List<MyObject> objects = new()
{
    new() { First = "ABC", Second = "DEF", Third = "GHI" },
    new() { First = "JKL", Second = "MNO", Third = "PQR" },
    new() { First = "STU", Second = "VWX", Third = "YZ" },
};

, a possible implementation is:

var flattenedObjects = objects
    .Select(obj => new[] { obj.First, obj.Second, obj.Third })
    .SelectMany(properties => properties);
    
var objectString = string.Join("_", flattenedObjects);

Printing the value of objectString to the console gives:

ABC_DEF_GHI_JKL_MNO_PQR_STU_VWX_YZ

Example fiddle here .

If you just want a one-line, handy C# without hard-coding property name you could try this:

string.Join("\n", objs.Select(o => string.Join("_", o.GetType().GetProperties().Select(p => p.GetValue(o)))));

This produces the following result:

"A_B_C\nD_E_F\nG_H_I"

with the object array as:

var objs = new MyObject[]
{
    new MyObject("A", "B", "C"),
    new MyObject("D", "E", "F"),
    new MyObject("G", "H", "I")
};

But please note that if your class has properties in other types then you might need a Where() between GetProperties() and the second Select() to exclude unwanted properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM