Add a separator to the list of items to display

I have a list of elements that I want to display with a separator between them in C #. Using a regular iterator, I get an extra delimiter at the beginning or end:

string[] sa = {"one", "two", "three", "four"};
string ns = "";
foreach(string s in sa)
{
    ns += s + " * ";
}
// ns has a trailing *:
// one * two * three * four * 

Now I can solve this using a for loop like this:

ns = "";
for(int i=0; i<sa.Length; i++)
{
    ns += sa[i];
    if(i != sa.Length-1)
        ns += " * ";
}
// this works:
// one * two * three * four

Although the second solution works, it does not look very elegant. Is there a better way to do this?

+3
source share
4 answers

You need a built-in method String.Join:

string ns = string.Join(" * ", sa);

If you want to do the same with other types of collections, then you can still use String.Joinit if you first create an array using LINQ ToArray:

string ns = string.Join(" * ", test.ToArray());
+19
source

, String. , , :

ns = sa.Join(" * ");

, , , :

public void Test_variants()
{
    const string item = "a";
    const int numberOfTimes = 100000;
    const string delimiter = ", ";
    string[] items = new List<string>(Enumerable.Repeat(item, numberOfTimes)).ToArray();
    string expected = String.Join(delimiter, items);

    Time(StringJoin, items, delimiter, expected);
    Time(Aggregate, items, delimiter, expected);
    Time(CheckForEndInsideLoop_String, items, delimiter, expected);
    Time(CheckForBeginningInsideLoop_String, items, delimiter, expected);
    Time(RemoveFinalDelimiter_String, items, delimiter, expected);
    Time(CheckForEndInsideLoop_StringBuilder, items, delimiter, expected);
    Time(RemoveFinalDelimiter_StringBuilder, items, delimiter, expected);
}

private static void Time(Func<string[], string, string> func, string[] items, string delimiter, string expected)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    string result = func(items, delimiter);
    stopwatch.Stop();
    bool isValid = result == expected;
    Console.WriteLine("{0}\t{1}\t{2}", stopwatch.Elapsed, isValid, func.Method.Name);
}

private static string CheckForEndInsideLoop_String(string[] items, string delimiter)
{
    string result = "";
    for (int i = 0; i < items.Length; i++)
    {
        result += items[i];
        if (i != items.Length - 1)
        {
            result += delimiter;
        }
    }
    return result;
}

private static string RemoveFinalDelimiter_String(string[] items, string delimiter)
{
    string result = "";
    for (int i = 0; i < items.Length; i++)
    {
        result += items[i] + delimiter;
    }
    return result.Substring(0, result.Length - delimiter.Length);
}

private static string CheckForBeginningInsideLoop_String(string[] items, string delimiter)
{
    string result = "";
    foreach (string s in items)
    {
        if (result.Length != 0)
        {
            result += delimiter;
        }
        result += s;
    }
    return result;
}

private static string CheckForEndInsideLoop_StringBuilder(string[] items, string delimiter)
{
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < items.Length; i++)
    {
        result.Append(items[i]);
        if (i != items.Length - 1)
        {
            result.Append(delimiter);
        }
    }
    return result.ToString();
}

private static string RemoveFinalDelimiter_StringBuilder(string[] items, string delimiter)
{
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < items.Length; i++)
    {
        result.Append(items[i]);
        result.Append(delimiter);
    }
    result.Length = result.Length - delimiter.Length;
    return result.ToString();
}

private static string StringJoin(string[] items, string delimiter)
{
    return String.Join(delimiter, items);
}

private static string Aggregate(string[] items, string delimiter)
{
    return items.Aggregate((c, s) => c + delimiter + s);
}

:

00:00:00.0027745    True    StringJoin
00:00:24.5523967    True    Aggregate
00:00:47.8091632    True    CheckForEndInsideLoop_String
00:00:47.4682981    True    CheckForBeginningInsideLoop_String
00:00:23.7972864    True    RemoveFinalDelimiter_String
00:00:00.0076439    True    CheckForEndInsideLoop_StringBuilder
00:00:00.0052803    True    RemoveFinalDelimiter_StringBuilder

, , , - String.Join, StringBuilder. , , StringBuilder. String , , , . numberOfItems, 10, :

00:00:00.0001788    True    StringJoin
00:00:00.0014983    True    Aggregate
00:00:00.0001666    True    CheckForEndInsideLoop_String
00:00:00.0002202    True    CheckForBeginningInsideLoop_String
00:00:00.0002061    True    RemoveFinalDelimiter_String
00:00:00.0002663    True    CheckForEndInsideLoop_StringBuilder
00:00:00.0002278    True    RemoveFinalDelimiter_StringBuilder

, , , , - . , String.Join .ToString() ( String.Join IEnumerable <. a > )

, , , :

public static string Join<T>([CanBeNull] this IEnumerable<T> items, [CanBeNull] string delimiter)
{
    StringBuilder result = new StringBuilder();
    if (items != null && items.Any())
    {
        delimiter = delimiter ?? "";
        foreach (T item in items)
        {
            result.Append(item);
            result.Append(delimiter);
        }
        result.Length = result.Length - delimiter.Length;
    }
    return result.ToString();
}

:

ns = sa.Join(" * ");
+3

, , .

var ns = sa.Aggregate( (c, s) => c + " * " + s);
+1

.

string ns = string.Join(" * ", sa);

, , :

string ns = "";
foreach(string s in sa)
{
    if (ns.Length != 0)
    {
        ns += " * ";
    }

    ns += s;
}

, , . , , , ( System.Collections.Generic.Dictionary < T, K > .Values), , - .

0

Source: https://habr.com/ru/post/1708189/


All Articles