IList <string> හෝ IEnumerable <string> වෙතින් කොමාවෙන් වෙන් කළ ලැයිස්තුවක් නිර්මාණය කිරීම


870

ක සිට ඈඳීම කොමා-වෙන් ලැයිස්තුව නිර්මාණය කිරීමට පිරිසිදුම ක්රමය කුමක්ද IList<string>හෝ IEnumerable<string>?

String.Join(...)ඒ අනුව ක්‍රියාත්මක වන අතර string[]ඒවා වර්ග පෙළක් බවට පහසුවෙන් IList<string>හෝ IEnumerable<string>පහසුවෙන් පරිවර්තනය කළ නොහැකි විට වැඩ කිරීමට අපහසු වේ.


5
ඔහ් ... අපොයි. ටෝආරේ ව්‍යාප්ති ක්‍රමය 3.5 කින් එකතු කිරීම මට මග හැරුණි:public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
ඩැනියෙල් ෆෝචූනොව්

1
CSV ලිවීමේ ක්‍රමයක් සොයමින් ඔබ මෙම ප්‍රශ්නයට පැමිණියේ නම්, අයිතම අතර කොමාව ඇතුළත් කිරීම ප්‍රමාණවත් නොවන බවත්, මූලාශ්‍ර දත්තවල මිල ගණන් සහ කොමාව සම්බන්ධයෙන් අසමත් වීමට හේතු වන බවත් මතක තබා ගැනීම වටී.
වියදම් කරන්න

Answers:


1485

.නෙට් 4+

IList<string> strings = new List<string>{"1","2","testing"};
string joined = string.Join(",", strings);

විස්තර සහ පෙර .නෙට් 4.0 විසඳුම්

IEnumerable<string>LINQ (.NET 3.5) සමඟ ඉතා පහසුවෙන් නූල් අරාව බවට පරිවර්තනය කළ හැකිය :

IEnumerable<string> strings = ...;
string[] array = strings.ToArray();

ඔබට අවශ්‍ය නම් සමාන සහායක ක්‍රමයක් ලිවීමට පහසුය:

public static T[] ToArray(IEnumerable<T> source)
{
    return new List<T>(source).ToArray();
}

ඉන්පසු එය මේ ආකාරයට අමතන්න:

IEnumerable<string> strings = ...;
string[] array = Helpers.ToArray(strings);

එවිට ඔබට ඇමතිය හැකිය string.Join. ඇත්ත වශයෙන්ම, ඔබ නෑ ඇති සහකාරියක් ක්රමය භාවිතා කිරීමට:

// C# 3 and .NET 3.5 way:
string joined = string.Join(",", strings.ToArray());
// C# 2 and .NET 2.0 way:
string joined = string.Join(",", new List<string>(strings).ToArray());

දෙවැන්න ටිකක් කටින් කටක් වුවත් :)

මෙම මෙන්ම ඉතා performant එය කිරීමට පහසුම ක්රමයක් විය හැකි අතර, - ඇතුළු (නමුත් ඒවාට පමණක් සීමා නොවේ) කාර්ය සාධනය වගේ හරියටම දේ ගැන තවත් ප්රශ්න, පවතින මේ එක .

.NET 4.0 වන විට, වැඩිපුර පැටවීම් තිබේ string.Join, එබැවින් ඔබට සැබවින්ම ලිවිය හැකිය:

string joined = string.Join(",", strings);

වඩා සරලයි :)


උපකාරක ක්‍රමයට අනවශ්‍ය ලැයිස්තු දෙකක් සෑදීම ඇතුළත් වේ. ගැටලුව විසඳීමට හොඳම ක්‍රමය මෙයද? එය ඔබම පුරෝකථනය කළ පුඩුවක් තුළට සංයුක්ත නොකරන්නේ ඇයි?
එරික්

4
සහායක ක්‍රමය නිර්මාණය කරන්නේ එක් ලැයිස්තුවක් සහ එක් අරාවක් පමණි. කාරණය වන්නේ ප්‍රති result ලය අරා එකක් මිස ලැයිස්තුවක් නොවිය යුතු බවයි ... තවද ඔබ ආරම්භ කිරීමට පෙර අරාවෙහි ප්‍රමාණය දැනගත යුතුය. හොඳම භාවිතයෙන් කියැවෙන්නේ ඔබ කළ යුතු නම් මිස LINQ හි ​​එක් වරකට වඩා ප්‍රභවයක් ගණනය නොකළ යුතු බවයි - එය සියලු ආකාරයේ අප්රසන්න දේවල් කිරීම විය හැකිය. ඉතින්, ඔබට ඉතිරිව ඇත්තේ බෆර වලට කියවීම සහ ඔබ යන විට ප්‍රමාණය වෙනස් කිරීම පමණි - එය හරියටම List<T>කරන්නේ එයයි. රෝදය ප්‍රතිනිර්මාණය කරන්නේ ඇයි?
ජෝන් ස්කීට්

9
නැත, කාරණය වන්නේ ප්‍රති result ලය සංයුක්ත නූලක් විය යුතු බවයි. මෙම ඉලක්කය සපුරා ගැනීම සඳහා නව ලැයිස්තුවක් හෝ නව පෙළක් සෑදීම අවශ්‍ය නොවේ. මේ ආකාරයේ .NET මානසිකත්වය මට දුකක් ගෙන දෙයි.
එරික්

40
ඒක තමයි. සෑම පිළිතුරක්ම ජෝන් ස්කීට් වෙත යොමු කරයි. මම දැන් යන්නේ Var PurchaseBooks = AmazonContainer.Where (p => p.Author == "ජෝන් ස්කීට්"). තෝරන්න ();
සැකරි ස්කොට්

3
@ codeMonkey0110: හොඳයි, එහි විමසුම් ප්‍රකාශනයක් තිබීම හෝ ඇමතීමෙන් පලක් නැත ToList. එය භාවිතා කිරීම හොඳයි string myStr = string.Join(",", foo.Select(a => a.someInt.ToString())).
ජෝන් ස්කීට්

179

FYI, එම .NET 4.0 අනුවාදය string.Join()සමහර ඇත අතිරේක overloads සමග වැඩ IEnumerableකරනවා වෙනුවට ඕනෑම වර්ගයක් සමග ගනුදෙනු කළ හැකි එක් ඇතුළු පමණක් අරා ක T:

public static string Join(string separator, IEnumerable<string> values)
public static string Join<T>(string separator, IEnumerable<T> values)

2
මෙය T.ToString () ක්‍රමය ලෙස හඳුන්වනු ඇත්ද?
පිලිප් ලැවෝයි

ජෝන් ගේ පිළිතුර ගැන මේ ගැන අදහස් දැක්වීමට සූදානම්ව සිටියේය. සඳහන් කිරීම ගැන ස්තූතියි.
ඩෑන් බෙචර්ඩ්

2
කෙසේ හෝ වස්තුවක දේපලක් මත මෙය කිරීමට? (උදා:. IEnumerable <සේවක> සහ සේවක වස්තුව එය මත වැලක් .SSN දේපළ, සහ කොමා ලබා වෙන් SSN ගේ ලැයිස්තුව)
granadaCoder

1
ඔබට එය දිගුව ක්‍රමයක් තෝරා ගත හැකි වුවද, එය මුලින්ම තෝරා ගත යුතුය. str = emps.Select(e => e.SSN).Join(",")
සේවියර් පොයිනාස්

66

මට මෙය කිරීමට පහසුම ක්‍රමය වන්නේ ලින්ක් Aggregateක්‍රමය භාවිතා කිරීමයි :

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)

21
එය ToArray + Join ට වඩා සංකීර්ණ (IMO) පමණක් නොව, එය තරමක් අකාර්යක්ෂමයි - විශාල ආදාන අනුක්‍රමයක් සහිතව, එය ඉතා නරක ලෙස ක්‍රියා කිරීමට පටන් ගනී.
ජෝන් ස්කීට්

36
තවමත්, එය වඩාත්ම ලස්සනයි.
මෙරිට්

2
ඔබට සමස්ත ස්ට්‍රිංබිල්ඩර් බීජයක් පෝෂණය කළ හැකිය, එවිට ඔබේ සමස්ථ කාර්යය බවට පත්වේ Func<StringBuilder,string,StringBuider>. ඉන්පසු ToString()ආපසු පැමිණි StringBuilder අමතන්න. ඇත්තෙන්ම එය එතරම් ලස්සන නැත :)
මැට් ග්‍රීර්

3
IMHO සඳහා අසන ලද ප්‍රශ්නය කිරීමේ පැහැදිලි ක්‍රමය මෙයයි.
ඩෙරෙක් මොරිසන්

8
පරෙස්සම් input.Countවිය යුතු 1. වඩා
Youngjae

31

කොමා වලින් වෙන් කරන ලද නූල් අගයන් ලැයිස්තුවක් නිර්මාණය කිරීමට ඇති පිරිසිදුම ක්‍රමය සරලවම යැයි මම සිතමි.

string.Join<string>(",", stringEnumerable);

මෙන්න සම්පූර්ණ උදාහරණයක්:

IEnumerable<string> stringEnumerable= new List<string>();
stringList.Add("Comma");
stringList.Add("Separated");

string.Join<string>(",", stringEnumerable);

සහායක ශ්‍රිතයක් කිරීමට අවශ්‍ය නැත, මෙය .NET 4.0 සහ ඊට ඉහළින් සාදා ඇත.


4
.NET 4 (සේවියර් ඔහුගේ පිළිතුරෙන් පෙන්වා දුන් පරිදි) සිට මෙය අදාළ වන බව සලකන්න.
ඩෙරෙක් මොරිසන්

මාසයකට අඩු පළපුරුද්දක් ඇති .NET 4 නවකතාවේ දෘෂ්ටි කෝණයෙන් මෙම පිළිතුර නිවැරදි බව සහ සංක්ෂිප්තභාවය පිළිබඳ කදිම එකතුවකි
ඩෙක්සිජන්

14

කාර්ය සාධනය අනුව සංසන්දනය කිරීම ජයග්‍රාහකයා වන්නේ "එය ලූප් කරන්න, sb. එය එකතු කරන්න, පසු පියවර කරන්න" යන්නයි. ඇත්ත වශයෙන්ම “ඊළඟට ගණන් කළ හැකි හා අතින් ගෙනයාම” එකම යහපතකි (stddev සලකා බලන්න).

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT


                Method |  Job | Runtime |     Mean |     Error |    StdDev |      Min |      Max |   Median | Rank |  Gen 0 | Allocated |
---------------------- |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:|
            StringJoin |  Clr |     Clr | 28.24 us | 0.4381 us | 0.3659 us | 27.68 us | 29.10 us | 28.21 us |    8 | 4.9969 |   16.3 kB |
 SeparatorSubstitution |  Clr |     Clr | 17.90 us | 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us |    6 | 4.9296 |  16.27 kB |
     SeparatorStepBack |  Clr |     Clr | 16.81 us | 0.1289 us | 0.1206 us | 16.64 us | 17.05 us | 16.81 us |    2 | 4.9459 |  16.27 kB |
            Enumerable |  Clr |     Clr | 17.27 us | 0.0736 us | 0.0615 us | 17.17 us | 17.36 us | 17.29 us |    4 | 4.9377 |  16.27 kB |
            StringJoin | Core |    Core | 27.51 us | 0.5340 us | 0.4995 us | 26.80 us | 28.25 us | 27.51 us |    7 | 5.0296 |  16.26 kB |
 SeparatorSubstitution | Core |    Core | 17.37 us | 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 us |    5 | 4.9622 |  16.22 kB |
     SeparatorStepBack | Core |    Core | 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82 us | 15.66 us |    1 | 4.9622 |  16.22 kB |
            Enumerable | Core |    Core | 17.00 us | 0.0905 us | 0.0654 us | 16.93 us | 17.12 us | 16.98 us |    3 | 4.9622 |  16.22 kB |

කේතය:

public class BenchmarkStringUnion
{
    List<string> testData = new List<string>();
    public BenchmarkStringUnion()
    {
        for(int i=0;i<1000;i++)
        {
            testData.Add(i.ToString());
        }
    }
    [Benchmark]
    public string StringJoin()
    {
        var text = string.Join<string>(",", testData);
        return text;
    }
    [Benchmark]
    public string SeparatorSubstitution()
    {
        var sb = new StringBuilder();
        var separator = String.Empty;
        foreach (var value in testData)
        {
            sb.Append(separator).Append(value);
            separator = ",";
        }
        return sb.ToString();
    }

    [Benchmark]
    public string SeparatorStepBack()
    {
        var sb = new StringBuilder();
        foreach (var item in testData)
            sb.Append(item).Append(',');
        if (sb.Length>=1) 
            sb.Length--;
        return sb.ToString();
    }

    [Benchmark]
    public string Enumerable()
    {
        var sb = new StringBuilder();
        var e = testData.GetEnumerator();
        bool  moveNext = e.MoveNext();
        while (moveNext)
        {
            sb.Append(e.Current);
            moveNext = e.MoveNext();
            if (moveNext) 
                sb.Append(",");
        }
        return sb.ToString();
    }
}

https://github.com/dotnet/BenchmarkDotNet භාවිතා කරන ලදි


11

වස්තු ලැයිස්තුවක නිශ්චිත දේපලකට සම්බන්ධ වීමට සෙවීමේදී මා මෙහි පැමිණි බැවින් (සහ එහි ToString () නොවේ) මෙහි පිළිගත් පිළිතුරට එකතු කිරීමකි:

var commaDelimited = string.Join(",", students.Where(i => i.Category == studentCategory)
                                 .Select(i => i.FirstName));


8

මෙම සාකච්ඡාවට මඳක් ප්‍රමාද වූ නමුත් මෙය මගේ දායකත්වයයි. මට IList<Guid> OrderIdsCSV නූලක් බවට පරිවර්තනය කළ යුතු නමුත් පහත දැක්වෙන්නේ සාමාන්‍ය වන අතර වෙනත් වර්ග සමඟ නවීකරණය නොකෙරේ.

string csv = OrderIds.Aggregate(new StringBuilder(),
             (sb, v) => sb.Append(v).Append(","),
             sb => {if (0 < sb.Length) sb.Length--; return sb.ToString();});

කෙටි හා පැණිරස, නව නූල් තැනීම සඳහා StringBuilder භාවිතා කරයි, අන්තිම කොමාව ඉවත් කිරීම සඳහා StringBuilder දිග එකින් එක හැකිලී CSV string යවයි.

Append()නූල් + කොමාව එක් කිරීමට බහු භාවිතා කිරීමට මම මෙය යාවත්කාලීන කර ඇත. ජේම්ස්ගේ ප්‍රතිපෝෂණයෙන් මම බැලීමට පරාවර්තකය භාවිතා කළෙමි StringBuilder.AppendFormat(). හැරෙනවා AppendFormat()එය අඩු පමණක් බහු භාවිතයට වඩා මේ සන්දර්භය තුළ කාර්යක්ෂම කරයි හැඩතලය string ඉදි කිරීමට භාවිතා වන StringBuilder Appends()ගේ.


.Net4 හි එම යාවත්කාලීනය ගැන මම නොදැන සිටියෙමි. මම වැඩ කරමින් සිටින ව්‍යාපෘතිය තවම පිම්මක් ගෙන නැත, ඒ නිසා මම දැන් මගේ පදික උදාහරණය දිගටම භාවිතා කරමි.
ඩේවිඩ් ක්ලාක්

2
ශුන්‍ය අයිතම IEnumerable ප්‍රභවයක් සමඟ මෙය අසාර්ථක වනු ඇත. sb.Length-- සඳහා සීමාවන් පරීක්ෂා කිරීම අවශ්‍යයි.
ජේම්ස් ඩූන්

සතුටුයි ජේම්ස්, මම මෙය භාවිතා කරන සන්දර්භය තුළ අවම වශයෙන් එක් ඕඩර් අයිඩ් එකක්වත් ඇති බවට මට සහතිකයි. මායිම් පරීක්ෂාව ඇතුළත් කිරීම සඳහා මම උදාහරණය සහ මගේම කේතය යන දෙකම යාවත්කාලීන කර ඇත (නිසැකවම).
ඩේවිඩ් ක්ලාක්

Ames ජේම්ස් මම හිතන්නේ sb.Length අමතන්න - හැක් කිරීම ටිකක් කටුකයි. Effective ලදායි ලෙස මම ඔබේ එක් එක් පුනරාවර්තනයේදී එය කරනවාට වඩා අවසානය දක්වා ඔබගේ “if (notdone)” පරීක්ෂණයෙන් වැළකී සිටිමි.
ඩේවිඩ් ක්ලාක්

1
Ases ජේම්ස් මගේ අදහස නම් මෙහි බොහෝ විට අසන ලද ප්‍රශ්නවලට එකකට වඩා නිවැරදි පිළිතුරක් ඇති අතර එකක් “හැක්” ලෙස හැඳින්වීමෙන් ඇඟවෙන්නේ එය මා විසින් ආරවුල් කරන වැරදි බවයි. මගපෙන්වන්නන් සුළු පිරිසකට මා ඉහත සඳහන් කළ ඩැනියෙල්ගේ පිළිතුර සම්පුර්ණයෙන්ම ප්‍රමාණවත් වනු ඇති අතර එය නිසැකවම වඩා සංක්ෂිප්ත / කියවිය හැකි මගේ පිළිතුරයි. මම මෙය මගේ කේතයේ එක් ස්ථානයක පමණක් භාවිතා කරන අතර මම කවදා හෝ කොමාවක් පරිසීමකය ලෙස භාවිතා කරමි. YAGNI පවසන්නේ ඔබට අවශ්‍ය නොවන දෙයක් ගොඩනඟන්න එපා. එක් වරකට වඩා වැඩි වාර ගණනක් කිරීමට මට අවශ්‍ය නම් ඩ්‍රයි අදාළ වේ. HTH.
ඩේවිඩ් ක්ලාක්

7

ටිකක් විකාර සහගත, නමුත් එය ක්‍රියාත්මක වේ:

string divisionsCSV = String.Join(",", ((List<IDivisionView>)divisions).ConvertAll<string>(d => d.DivisionID.ToString("b")).ToArray());

ඔබ පරිවර්තකය ලබා දුන් පසු ලැයිස්තුවකින් ඔබට CSV එකක් ලබා දෙයි (මේ අවස්ථාවේ දී d => d.DivisionID.ToString ("b")).

අශෝභන නමුත් ක්‍රියා - සමහර විට එය ව්‍යාප්ති ක්‍රමයක් බවට පත් කළ හැකිද?


7

මෙන්න මම එය කළ ආකාරය, වෙනත් භාෂාවලින් මා කළ ආකාරය භාවිතා කරමින්:

private string ToStringList<T>(IEnumerable<T> list, string delimiter)
{
  var sb = new StringBuilder();
  string separator = String.Empty;
  foreach (T value in list)
  {
    sb.Append(separator).Append(value);
    separator = delimiter;
  }
  return sb.ToString();
}

7

අප අවට සිටිය යුතු නිශ්චිත අවශ්‍යතාව ', උදා:

        string[] arr = { "jj", "laa", "123" };
        List<string> myList = arr.ToList();

        // 'jj', 'laa', '123'
        Console.WriteLine(string.Join(", ",
            myList.ConvertAll(m =>
                string.Format("'{0}'", m)).ToArray()));

4

අපට උපයෝගිතා ශ්‍රිතයක් ඇත, මේ වගේ දෙයක්:

public static string Join<T>( string delimiter, 
    IEnumerable<T> collection, Func<T, string> convert )
{
    return string.Join( delimiter, 
        collection.Select( convert ).ToArray() );
}

එකතු රාශියකට පහසුවෙන් සම්බන්ධ වීමට භාවිතා කළ හැකි:

int[] ids = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233};

string csv = StringUtility.Join(",", ids, i => i.ToString() );

ලැම්බඩාවට පෙර එකතු කිරීමේ පරාමිතිය අප සතුව ඇති බව සලකන්න.

ඔබට දැනටමත් නූල් ගණන් කිරීමක් තිබේ නම් ඔබ කළ යුත්තේ ToArray පමණි:

string csv = string.Join( ",", myStrings.ToArray() );

2
මට දීර්
LucH

ඔව්, ඔබට මෙය .ToDelimitedString දිගු කිරීමේ ක්‍රමයක් ලෙස ලිවිය හැකිය. මම මගේ තනි පේළිය සමඟ යමි. අන්තිම වර්‍ගය කැපීම සඳහා ස්ට්‍රිංබිල්ඩර් භාවිතා කරනවාට වඩා එක්වන්න.
කීත්

3

ඔබට ToArray භාවිතයෙන් IList අරාවකට පරිවර්තනය කළ හැකි අතර පසුව අරාව මත string.join විධානයක් ක්‍රියාත්මක කරන්න.

Dim strs As New List(Of String)
Dim arr As Array
arr = strs.ToArray

3

.NET 3.5 හි ඇති ලින්ක් දිගු භාවිතා කර ඒවා පහසුවෙන් අරාවකට පරිවර්තනය කළ හැකිය.

   var stringArray = stringList.ToArray();

3

අන් අය විසින් ලැයිස්තුගත කර ඇති එක් ක්‍රමයක් භාවිතා කරමින් ඔබ එය අරාවකට පරිවර්තනය කිරීමෙන් පසු පහත සඳහන් දේ වැනි දෙයක් භාවිතා කළ හැකිය:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Configuration;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
            string[] itemList = { "Test1", "Test2", "Test3" };
            commaStr.AddRange(itemList);
            Console.WriteLine(commaStr.ToString()); //Outputs Test1,Test2,Test3
            Console.ReadLine();
        }
    }
}

සංස්කරණය කරන්න: මෙන්න තවත් උදාහරණයක්


3

මෙම ලිපිය හරහා සිදුවීමට පෙර මම මෙම ගැටළුව විසඳා ගත්තෙමි. මගේ විසඳුම පහත පරිදි වේ:

   private static string GetSeparator<T>(IList<T> list, T item)
   {
       return (list.IndexOf(item) == list.Count - 1) ? "" : ", ";
   }

ලෙස හැඳින්වේ:

List<thing> myThings;
string tidyString;

foreach (var thing in myThings)
{
     tidyString += string.format("Thing {0} is a {1}", thing.id, thing.name) + GetSeparator(myThings, thing);
}

මටත් එබඳු පහසුවෙන් ප්‍රකාශ කළ හැකි අතර වඩාත් කාර්යක්ෂම වනු ඇත:

string.Join(“,”, myThings.Select(t => string.format(“Thing {0} is a {1}”, t.id, t.name)); 

3

මගේ පිළිතුර සමස්ත විසඳුමට සමාන ය, නමුත් පැහැදිලි නියෝජිත ඇමතුම් නොමැති බැවින් ඇමතුම්-බර අඩු විය යුතුය:

public static string ToCommaDelimitedString<T>(this IEnumerable<T> items)
{
    StringBuilder sb = new StringBuilder();
    foreach (var item in items)
    {
        sb.Append(item.ToString());
        sb.Append(',');
    }
    if (sb.Length >= 1) sb.Length--;
    return sb.ToString();
}

ඇත්ත වශයෙන්ම, කෙනෙකුට පරිමිතිය-ස්වාධීන වීමට අත්සන දිගු කළ හැකිය. මම ඇත්ත වශයෙන්ම sb. මම ඒ විසඳුම මතට ආවොත් මම ඒ ගැන කතා කරමි.


මට මුලින් අවශ්‍ය වූයේ මෙන්න:

public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter, Func<T, string> converter)
{
    StringBuilder sb = new StringBuilder();
    var en = source.GetEnumerator();
    bool notdone = en.MoveNext();
    while (notdone)
    {
        sb.Append(converter(en.Current));
        notdone = en.MoveNext();
        if (notdone) sb.Append(delimiter);
    }
    return sb.ToString();
}

තාවකාලික අරාව හෝ ලැයිස්තු ආචයනය අවශ්‍ය නොවන අතර හැක් StringBuilder Remove()හෝ Length--හැක් අවශ්‍ය නොවේ.

මගේ රාමුව පුස්තකාලයේ මම මේ ක්රමය අත්සන ද ඇතුළුව සෑම එකතුවක් මත වෙනස්කම් කිහිපයක් සිදු delimiterසහ converterභාවිතය සමග පරාමිතීන් ","හා x.ToString()පිළිවෙළින් පෙරනිමි ලෙස.


3

බලාපොරොත්තුව මෙය සරලම ක්‍රමයයි

 string Commaseplist;
 string[] itemList = { "Test1", "Test2", "Test3" };
 Commaseplist = string.join(",",itemList);
 Console.WriteLine(Commaseplist); //Outputs Test1,Test2,Test3

3

මම මෙම සාකච්ඡාවට පැමිණියේ MySQL ක්‍රමය සමඟ සිදු වූවාක් මෙන් නූල් වලට සම්බන්ධ වීමට හොඳ C # ක්‍රමයක් සොයමින් සිටියදීය CONCAT_WS(). මෙම ක්‍රමය ක්‍රමයට වඩා වෙනස් string.Join()වන්නේ නූල් NULL හෝ හිස් නම් එය බෙදුම්කරු ලකුණ එකතු නොකරයි.

CONCAT_WS (',', tbl.Lastname, tbl.Firstname)

ආපසු Lastnameඑන්නේ පළමු නම හිස් නම් පමණි

string.Join (",", strLastname, strFirstname)

strLastname + ", "එම අවස්ථාවේදීම නැවත පැමිණේ .

පළමු හැසිරීම අවශ්ය, මම පහත ක්රම ලිවීය:

    public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string strA, string strB, string strC = "")
    {
        return JoinStringsIfNotNullOrEmpty(strSeparator, new[] {strA, strB, strC});
    }

    public static string JoinStringsIfNotNullOrEmpty(string strSeparator, string[] arrayStrings)
    {
        if (strSeparator == null)
            strSeparator = "";
        if (arrayStrings == null)
            return "";
        string strRetVal = arrayStrings.Where(str => !string.IsNullOrEmpty(str)).Aggregate("", (current, str) => current + (str + strSeparator));
        int trimEndStartIndex = strRetVal.Length - strSeparator.Length;
        if (trimEndStartIndex>0)
            strRetVal = strRetVal.Remove(trimEndStartIndex);
        return strRetVal;
    }

2

එය කාර්යක්ෂම වන අයුරින් සිදු කිරීම සඳහා මම දිගු ක්‍රම කිහිපයක් ලිවීය:

    public static string JoinWithDelimiter(this IEnumerable<String> that, string delim) {
        var sb = new StringBuilder();
        foreach (var s in that) {
            sb.AppendToList(s,delim);
        }

        return sb.ToString();
    }

මෙය රඳා පවතී

    public static string AppendToList(this String s, string item, string delim) {
        if (s.Length == 0) {
            return item;
        }

        return s+delim+item;
    }

3
නූල් සංයුක්ත කිරීම සඳහා + ක්‍රියාකරු භාවිතා කිරීම විශිෂ්ට නොවේ, මන්ද එය සෑම අවස්ථාවකම නව නූලක් වෙන් කිරීමට හේතු වනු ඇත. තව දුරටත්, ස්ට්‍රිංබිල්ඩරය ව්‍යංගයෙන් නූලකට දැමිය හැකි වුවද, නිතර නිතර එසේ කිරීමෙන් (ඔබේ ලූපයේ සෑම ක්‍රියාවලියක්ම) බොහෝ විට නූල් සාදන්නෙකු වීමේ අරමුණ පරාජය කරයි.
ඩැනියෙල් ෆෝචූනොව්

2

ඔබට භාවිතා කළ හැකි .ToArray()මත Listsහා IEnumerables, පසුව භාවිතා String.Join()කිරීමට ඔබට අවශ්ය විය.


0

ඔබට සම්බන්ධ වීමට අවශ්‍ය නූල් වස්තු ලැයිස්තුවේ තිබේ නම්, ඔබටත් මේ වගේ දෙයක් කළ හැකිය:

var studentNames = string.Join(", ", students.Select(x => x.name));

0

කොමා වලින් වෙන් කරන ලද ලැයිස්තුවක් සෑදීම සඳහා IList<string>හෝ IEnumerable<string>, භාවිතා කිරීමට අමතරව string.Join()ඔබට මෙම StringBuilder.AppendJoinක්‍රමය භාවිතා කළ හැකිය :

new StringBuilder().AppendJoin(", ", itemList).ToString();

හෝ

$"{new StringBuilder().AppendJoin(", ", itemList)}";
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.